Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

comment on

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

demerphq (re)discovered this little glitch, and describes it well. I'm going to add a bit, since it can be helpful to take a different view of the same problem. Here are some minimal cases, leaving off strict and warnings just because they're not very relevant...

{ my $foo = "Foo!\n"; sub makefoo { *foo = sub { print $foo }; $foo; } } makefoo(); foo();

Prints 'Foo!' just as you'd expect. Or as I'd expect, anyway.

{ my $foo = "Foo!\n"; sub makefoo { *foo = sub { print $foo }; } } makefoo(); foo();

Prints nothing at all. If you expected this, you're either deeper in Perl lore than I, or you have a sick mind. That's an inclusive or.

Thing is, the package sub &foo is being defined at compile time, and the anonymous sub within only at run time. That lone $foo statement in the first example, is a reference to the variable $foo, keeping it alive after $foo has gone out of scope, and available for the newly generated sub. Without the seemingly irrelevant statement, $foo is undefined. Apparently Perl doesn't look inside the subroutine to be generated for such references. Which makes some sense, I guess, because figuring out what code will be generated later is hard. I guess. Anyway...

{ my $foo = "Foo!\n"; *makefoo = sub { *foo = sub { print $foo }; } } makefoo(); foo();

Prints 'Foo!'. &makefoo is defined at runtime.

my $foo = "Foo!\n"; sub makefoo { *foo = sub { print $foo }; } makefoo(); foo();

Prints 'Foo!'. Fine and dandy... no closure-type stuff going on here. Which is evident because:

my $foo = "Foo!\n"; sub makefoo { *foo = sub { print $foo }; } $foo = "Moo!\n"; makefoo(); foo();

Prints 'Moo!'. $foo is still around when &makefoo gets called, so even though &makefoo doesn't carry a reference around with it, the var is still hanging around for &makefoo to use.

In my book, the compile-time run-time stuff definitely counts as weird. The $foo in the generated sub isn't doing what I mean, and the $foo statement in &makefoo is doing more than I expect. Oh well. No sense whining... I guess it's good for me. ;-)

In reply to Re: Funkyness with closures... by Petruchio
in thread Funkyness with closures... by demerphq

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 the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others wandering the Monastery: (6)
    As of 2020-03-31 01:35 GMT
    Find Nodes?
      Voting Booth?
      To "Disagree to disagree" means to:

      Results (177 votes). Check out past polls.