Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Thanks for the clarification. Indeed, your example shows that my statement about the function being compiled at run time is completely wrong!

Now that I understand it, I think your example offers a great insight into scoping issues, and the difference between compile- and run-time. Let's trace through what happens (or at least what seems to me to be happening).

  1. The original definition of f is compiled.
  2. The definition of g is compiled.

    When we read the my ( $a ) = @_ declaration, we set aside space for $a, but do not yet assign anything to it. This pre-allocated space will be used only in our first call to g.

    Next, we compile the re-definition of f, triggering both the “Subroutine redefined” and the “Variable "$a" will not stay shared” warnings. At this point, we're still in the compilation phase.

    Notice that f is closing over the pre-allocated copy of $a—that is, the one that will be used in the first call to g. This is the weirdness that you're observing.

    To see that all this is happening at compile time, you can add the code block

    BEGIN { $a = "Hi from compile time" }
    before the re-definition of f and observe the changes at run time.

  3. We finish compilation, and assign 'AAA' to $a on line 6. However, this is the ‘outer’ $a, not the one * in the scope of g, so it has no effect on the now-re-defined f.
  4. We run the call to f on line 11. Since f has already been re-defined, we call the re-defined subroutine. Since $a still hasn't been initialised, we get the “Use of uninitialised value” warning. (I think ikegami might prefer “Use of unitialised variable”. :-) )
  5. Nothing happens at run time as we pass over the definition of g—that was dealt with already at compile time.
  6. We call f again on line 22. Since nothing has happened since the last call to f, we get the same result.
  7. We call g with argument 'BBB'. This 'BBB' gets assigned to the pre-allocated $a, which is the one that f closed over, so f ‘sees’ this new value. The re-definition of f is ignored at run time; that happened at compile time.
  8. We say the existing value of the ‘outer’ $a (it's 'AAA', because we assigned it back on line 6), assign a new value, 'CCC', to the ‘outer’ $a, and say that new value. None of this affects the variable $a that f closed over.
  9. We call f again on line 27. Since the $a that f closed over, as opposed to the ‘outer’ one to which we just assigned, has and forever will have the value 'BBB', that's the value that f uses.
  10. We call g again. As g runs, it allocates a new lexical variable $a that has nothing to do with the one that f closed over. (This behaviour is precisely of what the warning about variables not staying shared is—well—warning you.) As a result, the assignment to this new $a has no effect on f. We again skip over the re-definition of f at run time, since we already took care of it at compile time.
  11. We call f again on line 29. Since nothing has changed with its squirreled-away $a, the result is the same as when we called it on line 27.

* I should be careful referring to “the one in the scope of g”, since, as we shall see, each run of g gets its own fresh lexical $a. However, “one of the ones in the scope of g” is a mess to read, so the imprecision stays.

In reply to Re^4: closure clarity, please by JadeNB
in thread closure clarity, please by 7stud

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, 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, 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.
  • Log In?

    What's my password?
    Create A New User
    and all is quiet...

    How do I use this? | Other CB clients
    Other Users?
    Others taking refuge in the Monastery: (3)
    As of 2018-03-25 03:52 GMT
    Find Nodes?
      Voting Booth?
      When I think of a mole I think of:

      Results (300 votes). Check out past polls.