Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

why need my in a foreach loop?

by szabgab (Priest)
on Nov 28, 2010 at 04:36 UTC ( #874062=perlquestion: print w/ replies, xml ) Need Help??
szabgab has asked for the wisdom of the Perl Monks concerning the following question:

use strict; use 5.010; foreach my $word (qw(abc def ghi)) { say $word; }
When using strict perl requires to declare even the loop variable of a foreach loop. Why is that? After all the $word variable in the above example is an alias to the values and won't have any effect outside of the loop. Even if written this way:
use strict; use 5.010; my $word = "hello"; foreach $word (qw(abc def ghi)) { say $word; } say $word; # word is "hello" here
Why is this code not allowed?
use strict; use 5.010; foreach $word (qw(abc def ghi)) { say $word; } # generate syntax error if $word is used here

Comment on why need my in a foreach loop?
Select or Download Code
Re: why need my in a foreach loop?
by ikegami (Pope) on Nov 28, 2010 at 04:55 UTC

    When using strict perl requires to declare even the loop variable of a foreach loop.

    It can use package variables, for starters.

    our $foo; sub f { print("$foo\n"); } for $foo (qw( a b c )) { f(); # Prints a, b and c. }

    Foreach loops existed long before "my".

    Why is this code not allowed?

    It generates an error for all instances of $word since you never declared it and you asked to make such things errors.

      Here's the difference:

      use strict; use warnings; use 5.010; our $foo = 'hello'; sub f { print("$foo\n"); } for my $foo (qw( a b c )) { f(); } --output:-- hello hello hello

      In ikegami's example, the my is omitted in the for loop, which causes the for loop to change the global variable $foo--and the subroutine prints the global $foo (i.e. the subroutine is a closure).

        the subroutine is a closure

        Backwards. It works because the subroutine doesn't capture package variables. If you switched our for my in my snippet, you'd have a closure, and you'd get a different result.

Re: why need my in a foreach loop?
by PeterPeiGuo (Hermit) on Nov 28, 2010 at 06:09 UTC

    Why not? What's the benefit of not requiring this? What's the benefit of not having consistent rule here?

    Peter (Guo) Pei

      The OP points out that there's no real difference between for $lex (...) and for my $lex (...). The "my" is just useless noise. As such, the declaration could be implicit.

      It's reasonable, but it's not true because foreach loops don't just work with lexicals.

        The foreach loop always works with an alias. IMHO the variable is never connected to anything outside the for loop so the values never "leak" out of the loop. If I am mistaken, please give an example when that variable is connected to something else as well.
Re: why need my in a foreach loop?
by moritz (Cardinal) on Nov 28, 2010 at 07:47 UTC
    use strict 'vars' basically says "all variables that you use must be declared (unless they contain :: or ').

    Using a variable in a loop is not different from using a variable in an assignment: it can either use an existing one, or it can be a fresh one, declared with my.

    Or put another way: use strict; forces you to be explicit about your declarations. Having some construct doing implicit declarations, at least in some circumstances, goes against the entire idea of strict.

    Update: Perl 6 gets around this by having other declarative syntax forms. Signatures can be used for that, either by being attached to a routine, or in the form of a lambda:

    # | declares $x in the scope of the block my $lambda = -> $x { $x * $x } # reused in loop syntax: for <a b cd> -> $x { say $x } # | declares $x in the scope of the block sub square($x) { $x * $x }
      apparently most people thought here I don't understand that use strict (or more specifically the 'vars' part of it) forces the need of "my". My question why do we need that in a for-loop.

      As you also know way better than I, Perl 6 can get by without this. I don't see when does that "my" do any useful work there. It is not the "my" that defines the scope of this variable so IMHO it is there only to satisfy "use strict".

        I love that in Perl6 loops automatically create localized variables: (may look familiar to Gabor)

        for @names -> $n { say $n; }

        Why not backport that feature into Perl5. Maybe only if warnings and strict and features are full on.<?p>

        As Occam said: Entia non sunt multiplicanda praeter necessitatem.

        It is not the "my" that defines the scope of this variable so IMHO it is there only to satisfy "use strict".

        I can't think of any other cases in which Perl 5 automatically lexicalizes a named variable without my; I think it's a (useful) consistency.

Re: why need my in a foreach loop?
by JavaFan (Canon) on Nov 28, 2010 at 12:08 UTC
    In the old days of perl5,
    foreach my $var (LIST) { .. }
    was a syntax error. You had to write:
    my $var; foreach $var (LIST) { .. }
    or use a package variable, as pointed out earlier in this thread.

    I remember the days that

    foreach my $var (LIST) { .. }
    was actually seen as progress...

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://874062]
Approved by McDarren
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2014-07-22 07:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (106 votes), past polls