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

{ my $subref; { my $foo = Foo->new; $subref = sub { # outer print "FOO: $foo\n"; }; } print "Outside!\n"; $subref->(); }
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:
Outside FOO: Foo=HASH(0x1a7eefc) DESTROY CALLED at xx line 15.

In the second step we put the inner closure back in like this:

{ my $subref; { my $foo = Foo->new; $subref = sub { # outer print "FOO: $foo\n"; sub { # inner print "FOO: $foo\n"; }; }; } print "Outside\n"; $subref->(); }
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 ...

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

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.