Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re: Funkyness with closures...

by Petruchio (Vicar)
on Sep 30, 2001 at 06:48 UTC ( #115701=note: print w/replies, xml ) Need Help??

in reply to Funkyness with closures...

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. ;-)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://115701]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (8)
As of 2020-04-08 17:54 GMT
Find Nodes?
    Voting Booth?
    The most amusing oxymoron is:

    Results (45 votes). Check out past polls.