in reply to foreach localizing variables
Your code commented:
my $value = "four"; # lexical variable my @array = ( "one", "two", "three" ); foreach $value (@array) { # variable $value inside the loop is set # to each element of @array at runtime print "foreach value: $value\t"; function(); } # outer scope lexical $value visible here sub function { # outer scope lexical $value visible here # with its initial value print "function value: $value\n"; }
Had you used a package global throughout, the outcome would have been different:
$value = "four"; my @array = ( "one", "two", "three" ); foreach $value (@array) { print "foreach value: $value\t"; function(); } sub function { print "function value: $value\n"; } __END__ foreach value: one function value: one foreach value: two function value: two foreach value: three function value: three
What about allocating a sub in a block's scope? Let's look at this weird construct:
my $value = "four"; my @array = ( "one", "two", "three" ); foreach $value (@array) # note outer $value variable { print "foreach value: $value\t"; function(); sub function { print "function value: $value\n"; } } __END__ foreach value: one function value: four foreach value: two function value: four foreach value: three function value: four
The result is the same, although the sub is allocated inside the for() block scope. Why? Because the sub, on compilation, gets the outer $value, whereas the loop iteration variable is an alias to the outer.
But what about that?
my $value = "four"; my @array = ( "one", "two", "three" ); foreach my $value (@array) { print "foreach value: $value\t"; function(); sub function { print "function value: $value\n"; } } __END__ foreach value: one function value: foreach value: two function value: foreach value: three function value:
How come? Declaring the loop variable as a my variable to the loop block, the inner loop gets that at compile time, and closes over it (it's a closure), and this variable is initialized empty (assignment happens at run time). The inner sub variable is different from the aliased loop variable.
All this is presented here with a lot of handwaving. The perl sources might provide a clue about what's really happening. Pass arguments to your subroutines to be save.
--shmem
_($_=" "x(1<<5)."?\n".q·/)Oo. G°\ /
/\_¯/(q /
---------------------------- \__(m.====·.(_("always off the crowd"))."·
");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: foreach localizing variables
by AndyJ (Initiate) on Feb 07, 2008 at 11:51 UTC | |
by shmem (Chancellor) on Feb 07, 2008 at 12:47 UTC |