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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.