Mmhh, interesting ... well the first thing to notice is the warning perl creates about useless use of reference constructor. This indicates that you are creating a reference to an anonymous subroutine (the outer one) but actually you are doing nothing with it. The strange thing is that perl does not complain about the inner one ... I have no idea why!
Ok, so let's change this a bit
Now perl produces no more warning because we save the (outer) anonymous sub in a variable. The destroy method is called correctly as I deleted the inner sub. The closure we created is working as expected, producing the output:{ my $subref; { my $foo = Foo->new; $subref = sub { # outer print "FOO: $foo\n"; }; } print "Outside!\n"; $subref->(); }
Outside FOO: Foo=HASH(0x1a7eefc) DESTROY CALLED at xx line 15.
In the second step we put the inner closure back in like this:
What happens now is mainly guessing on my part - so please correct me if I'm wrong. The inner closure is not handled like the outer closure by perl (e.g. no warning). It seems, perl doesn't know how to deal with these nested closures. In this case, the inner one could be completely ignored as there is no reference to the anonymous sub created and so the object could be destroyed once $foo leaves the scope. But perl wants to be on the safe side and does not destroy the object until the end of the program. That could be called a memory leak ...{ my $subref; { my $foo = Foo->new; $subref = sub { # outer print "FOO: $foo\n"; sub { # inner print "FOO: $foo\n"; }; }; } print "Outside\n"; $subref->(); }
Maybe someon with more knowledge about the perl internals could shed some light on this ...
Update: Thanks to crazyinsomniac I now see the light :) The reference to the inner anonymous subroutine is - as it is the last statement in a subroutine - implicitly returned. That's the reason why perl doesn't complain...
-- Hofmator
In reply to Re: nested subs cause DESTROY block to not get hit
by Hofmator
in thread nested subs cause DESTROY block to not get hit
by eak
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |