When the "my $x;" statement is compiled, it creates a slot for a lexical. When the "foo" and "bar" subroutines are compiled, they "close around" the instance of $x that is in that slot and will forever use that instance. The first time through the loop, the run-time effect of the "my $x;" statement is that "this lexical hasn't been used yet so I don't need to waste time re-initializing it". The second time through the loop, the run-time effect of the "my $x;" statement needs to create a new instance of $x because that instance has been used and is still being reference and so can't just be re-used. At this point, the $x being referenced in the loop is different from the $x being referenced in the closures (subs).
I'm not surprised that the first time a "my" statement gets run, that it knows to not waste time creating a new instance. I don't know the technical details of how it determines that it is the first time that it has been run, or, if that isn't what it is determining, why it doesn't consider the $x instance that was already manipulated by the closures worthy of being replaced by a new instance. Or perhaps the "create a new instance" actually happens when the scope is left rather than when it is re-entered. I'd be interested in more details on this from someone more familiar with Perl guts.
Consider:
for( 1..3 ) { foo(); REDO: foo(); my $x; sub foo { print 'f', ++$x, $/; } print ++$x, $/; goto REDO if 2 == $_++; } __END__ f1 f2 3 f4 f5 1 f6 2 f7 f8 1
Note that the "2" line shows that the goto re-running the "my" statement doesn't re-initialize the $x lexical. This might support the theory that a new $x instance is created when the lexical scope is left. I might call this a "bug" except for this is too esoteric and I don't think code should depend on such so I don't care. But it is interesting.
- tye
In reply to Re^4: Trying to understand closures (instances)
by tye
in thread Trying to understand closures
by shine22vn
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |