in reply to Hidden Secrets of PERL

I would try unravelling stuff in the Obfuscation section.

BTW congratulations. It has been a long time since something was pointed out to me about Perl that truly made me go, Ick! You succeeded.

BTW trading oddities, why do the following two programs print different things?

####### ## A ## ####### use strict; my $foo; $foo = "outside"; for $foo (qw(a b c)) { print_foo(); } sub print_foo { print "$foo\n"; } __END__ ####### ## B ## ####### use strict; our $foo; $foo = "outside"; for $foo (qw(a b c)) { print_foo(); } sub print_foo { print "$foo\n"; } __END__

Replies are listed 'Best First'.
Re^2: Hidden Secrets of PERL
by Hue-Bond (Priest) on Oct 11, 2006 at 22:58 UTC

    If the variable that is going to hold each value in an loop already exists as a lexical one (first example), foreach creates a new lexical whose scope is the loop block. If it exists as a package global (second example), foreach localizes it, thus making its scope dynamic. That's why second example's print_foo sees the dynamic content.

    --
    David Serrano

      Indeed and this is documented in perlsyn under the heading "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.

      OTOH, it doesn't seem to be really localized, instead, it appears to be a totally different lexical.

Re^2: Hidden Secrets of PERL
by fenLisesi (Priest) on Oct 12, 2006 at 08:49 UTC
    Allow me to toil in some scrivener's work. In the "Non-Lexical Loop Iterators" section of PBP, the oracle speaks:
    Always declare a for loop iterator variable with my.
    and goes on to explain that, if there happens to be a lexical variable with the same name as the loop variable declared before the loop, that lexical variable is not reused within the loop, but a brand new independent lexical variable is implicitly created to take effect within the scope of the loop alone. Quoting the discussion there:
    This behaviour is contrary to all reasonable expectation. Everywhere else in Perl, when you declare a lexical variable, it is visible throughout the remainder of its scope, unless another explicit my declaration hides it.
    Update: wfsp sent me a link to this related node.
      The reason is history. The ability to write:
      foreach my $variable (LIST) {...}
      was relatively recent (5.004 I think). Before one had to write
      my $variable; foreach $variable (LIST) {...}

      As usual, it's combining old Perl DWIM, new features and backwards compatability that leads to oddities like this. Luckely, for most people, it all just works, and old programs don't break.