in reply to Closures & aliases

Foreach Loops

The "foreach" loop iterates over a normal list value and sets the variable VAR to be each element of the list in turn. If the variable is preceded with the keyword "my", then it is lexically scoped, and is therefore visible only within the loop. Otherwise, the variable is implicitly local to the loop and regains its former value upon exiting the loop. If the variable was previously declared with "my", it uses that variable instead of the global one, but it's still localized to the loop. This implicit localisation occurs only in a "foreach" loop.

$foo was bound to test() originally but then you slapped a localization over the binding so it was a separate variable being written to.

perl -le 'my $foo;print \$foo;for $foo(1){print \$foo}' SCALAR(0x8152348) SCALAR(0x81441c8)

Replies are listed 'Best First'.
Re^2: Closures & aliases
by BrowserUk (Patriarch) on Jun 06, 2004 at 00:51 UTC

    Okay. That explains the code, but now begs the question, why is it so?

    I can think of two or three situations where I would like to use a pre-declared loop variable in a for loop and have it retain it's value afterwards.

    What I cannot think of, is any benefit for it not doing so, nor any major/common caveat that it avoids.

    Is a pre-declared, lexical loop variable localized (something that you cannot ordinarially do) for the loop body duration, for a "least surprise" or other DWIM benefit? Or is it simple a side-effect or caveat of the implementation?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
      A for loop and a foreach loop are slightly different. Adding to the confusion is that for and foreach are synonyms for each other (no pun intended).
      for my $y ( @a ) {...}
      makes $y an alias for one element of @a each time through the loop. Writing
      foreach my $y ( @a ) {...}
      is identical, but 4 chars longer to type.

      On the other hand,

      foreach ( $x=0; $x < $#a; $x++ ) {my $y=$a[$x];...}
      would behave similarly, except $y is not an alias for elements of @a, but a copy. And using
      for ( $x=0; $x < $#a; $x++ ) {my $y=$a[$x];...}
      would not change the behavior here either.

      Which form the compiler chooses is based on the argument list to for/foreach, and not the name itself!

      I hope that helps :|

      Update: I wish I'd have said it more like hv did below. Maybe he'll volunteer to edit for me in the future ;)

      A for loop and a foreach loop are slightly different.
      I attempted (but failed) to say that the OP seemed to understand them as different entities. The only difference is what follows the keyword, and not the keyword itself.

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        A for loop and a foreach loop are slightly different.

        No, they are synonyms, and therefore identical.

        Adding to the confusion is that for and foreach are synonyms for each other

        Yes, they are synonyms, and therefore identical.

        for and foreach are synonyms. They are therefore identical. However they are used (interchangeably) to introduce two completely different types of loop, the "C-style for loop":

        LABEL for (EXPR; EXPR; EXPR) BLOCK
        and another one for which I know no convenient name (the "list-style for loop"?):
        LABEL for VAR (LIST) BLOCK

        It is unfortunate that the presentation of these two loop styles in perlsyn implies that the keyword for the first is "for" and for the second is "foreach", since that isn't true: the two are synonyms, hence interchangeable.

        Hope this helps. :)

        (no pun intended).

        None implied.

        Hugo

      I don't know why, I jsut know it is documented that way. I guess foreach could make a copy of the value for each element but I'd guess it'd be slow then.
Re^2: Closures & aliases
by ambrus (Abbot) on Jun 06, 2004 at 18:13 UTC

    I don't see why that would explain the behaiviour, as for localizes the variable lexically, just like local. That's probably so that you can use $_ implicitly even if it's the index variable of a for loop, for example print and print uc for hello prints helloHELLO.

    This reply, however, has an answer to your question.