in reply to for loops, closures
For this one, I got:for ($i = 1; $i <= 8; $i++) { print "\\\$i is ", \$i, "\n"; my $c = sub { print "\$i is $i\n" }; print "\$c is $c\n"; push @codes, $c; }
showing that we are neither looking at distinct $i nor a closure (the addresses are all identical). Now, let's add a my declaration:\$i is SCALAR(0x80ce98c) $c is CODE(0x80cea04) \$i is SCALAR(0x80ce98c) $c is CODE(0x80cea04) \$i is SCALAR(0x80ce98c) $c is CODE(0x80cea04) \$i is SCALAR(0x80ce98c) $c is CODE(0x80cea04) \$i is SCALAR(0x80ce98c) $c is CODE(0x80cea04) \$i is SCALAR(0x80ce98c) $c is CODE(0x80cea04) \$i is SCALAR(0x80ce98c) $c is CODE(0x80cea04) \$i is SCALAR(0x80ce98c) $c is CODE(0x80cea04)
and notice that we now get a closure (the coderef addresses change):for (my $i = 1; $i <= 8; $i++) { print "\\\$i is ", \$i, "\n"; my $c = sub { print "\$i is $i\n" }; print "\$c is $c\n"; push @codes, $c; }
So, even though these are all closures, they are all linked to the same now changed $i. This will protect them for when the $i goes out of scope, but they still all share the same one. What we need is to have a "different" $i each time:\$i is SCALAR(0x80ce974) $c is CODE(0x80c83ac) \$i is SCALAR(0x80ce974) $c is CODE(0x80d22f8) \$i is SCALAR(0x80ce974) $c is CODE(0x80d2364) \$i is SCALAR(0x80ce974) $c is CODE(0x80d23d0) \$i is SCALAR(0x80ce974) $c is CODE(0x80d243c) \$i is SCALAR(0x80ce974) $c is CODE(0x80d24a8) \$i is SCALAR(0x80ce974) $c is CODE(0x80d2514) \$i is SCALAR(0x80ce974) $c is CODE(0x80d2580)
Ahh, there we go, now we got it:foreach my $i (1..8) { print "\\\$i is ", \$i, "\n"; my $c = sub { print "\$i is $i\n" }; print "\$c is $c\n"; push @codes, $c; }
See the distinct $i variables, as well as the closures created for them!\$i is SCALAR(0x80c83ac) $c is CODE(0x80ce95c) \$i is SCALAR(0x80d21b8) $c is CODE(0x80d21c4) \$i is SCALAR(0x80d2230) $c is CODE(0x80d223c) \$i is SCALAR(0x80d22a8) $c is CODE(0x80d22b4) \$i is SCALAR(0x80d2320) $c is CODE(0x80d232c) \$i is SCALAR(0x80d2398) $c is CODE(0x80d23a4) \$i is SCALAR(0x80d2410) $c is CODE(0x80d241c) \$i is SCALAR(0x80d2488) $c is CODE(0x80d2494)
Hopefully, this kind of reference-to examination will give you more clues faster when you can't see why things are shared or not. Very helpful for those $x won't stay shared diagnostics.
-- Randal L. Schwartz, Perl hacker
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
RE: Closures (was Re: for loops)
by Aighearach (Initiate) on Aug 21, 2000 at 05:26 UTC |