http://www.perlmonks.org?node_id=982346


in reply to Reference to guard not released

Because you never call the sub that contains the Scope::Guard;
Try:
use strict; use Scope::Guard; my $x; my $code = do { my $g; my $s=sub { $g = Scope::Guard->new( sub { warn "destroyed"; $x ; +} ) }; $s->(); }; $code->(); $code=undef; warn "end"; ---- Not a CODE reference at /tmp/pt1 line 11. destroyed at /tmp/pt1 line 7 during global destruction.

You are also creating a sub that references a 'global' ($x) that won't go out of scope until BOTH the global is 'done' and until the anonymous sub (with a reference in Scope::Guard, presumably), goes out of scope -- and it may not destroy it's reference until the program has exited (i.e. it may be in an allocated hash, once the allocated hash has been destroyed, the 'sub' goes away, and then the '$x' goes away, and everyone is destroyed...

AAiieee....

Replies are listed 'Best First'.
Re^2: Reference to guard not released
by roman (Monk) on Jul 18, 2012 at 06:07 UTC

    I don't understand. Which sub I don't call? The sub which creates the guard? Of course it is called! It is stored in $code and it is called immediately after do. Your example is something very different.

    The only purpose of do is to create a variable which is referenced only from the anonymous sub.

    my $x; my $code = do { my $g; sub { $g = Scope::Guard->new( sub { warn "destroyed"; $x ; } ) }; }; $code->(); undef $code; warn "end";

    I also don't understand the rest of your comment. The problem is not that $g references something, but that it is referenced from somewhere. But what keeps the reference to $g?

    My example is the very simplification of real scenario I came across in asynchronous programming. I have two callbacks sharing a resource (handle). The resource is stored in lexical variable visible only in these two subs. First callback is called, creates the resource ($code->()) and goes out of scope. Second callback is scheduled to run. Than the process is cancelled and the second callback is cancelled from queue and goes out of scope (undef $code - here I simplified to one callback only). I expect the resource to be released then.