Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re^3: Reference to guard not released

by perl-diddler (Hermit)
on Jul 19, 2012 at 00:23 UTC ( #982563=note: print w/ replies, xml ) Need Help??


in reply to Re^2: Reference to guard not released
in thread Reference to guard not released

So what is ScopeGuard supposed to be guarding? "$x"?

You declared $x at the global level. Is that what you are protecting? That doesn't get destroyed until the program exits...

You declared an anonymous sub inside scopeguardnew... that's also unlikely to be destroyed until your program exits -- because Scope::Guard is holding a "reference" to the interior sub (likely)... and, AT THE LEAST, the 'my $x' is declared at the global level -- so it won't be destroyed until the prog exits...

But I checked, and putting braces around the dcl of $x, doesn't change the output. So I would bet scopeguard has stored a reference to the interior sub so it can be called when "$x" goes out of scope.

But you referenced "$x" in side the sub that scope guard stored...--- so $x can't go out of scope until the interior sub (that you passed to SG->new) disappears -- and it won't disappear until your prog exits...

All you did by assigning undef to $code is lose the reference to the outside sub.. SGnew still has a reference to the inner sub and $x...

The reference to $x, that is in the anonymous sub, is referred to in jargon, as a "closure".

I'd guess that's because it creates a closed "ecosystem" that holds the anon-sub and the anon-sub's copy of $x -- no one changing '$x', after that sub is defined, will affect the value that is stored (referenced, really), in that inner sub (inside the new)...

Does that make more sense?


Comment on Re^3: Reference to guard not released
Re^4: Reference to guard not released
by roman (Monk) on Jul 19, 2012 at 11:25 UTC

    I don't want to protect $x. I just want to touch $x (store the value into it) when Scope::Guard object gets destroyed, i.e. when all references to it go out of scope.

    In simple and obvious example below, the $g gets destroyed and inner sub called immediately after it goes out of scope.

    use strict; use Scope::Guard; my $x; { my $g = Scope::Guard->new(sub {$x; warn "destroyed"}); } warn "end";
    But I checked, and putting braces around the dcl of $x, doesn't change the output. So I would bet scopeguard has stored a reference to the interior sub so it can be called when "$x" goes out of scope.

    Your bet is wrong. The sub is called the guard gets destroyed, not the object it references. Look at the Scope::Guard code. Is very short and self explanatory.

    All you did by assigning undef to $code is lose the reference to the outside sub.. SGnew still has a reference to the inner sub and $x...

    Yes, but when I lose reference to the outside sub, I should also lose the last reference to $g, because the sub is the only object which sees $g. But it doesnot happen.

    Does that make more sense?

    I need to read comments above, but it still doesnot make more sense to me. However constructed is the inner sub (stored in $g) it is just another object referenced by $g, not referencing it. So I don't understand how it (the inner sub) can affect the reference count to $g.

    The example I gave doesnot make sense itself, it is just the simplest demonstration of the behaviour I was able to make up. My original was more like the test below: ($x is \@res, I just try to log into res, when the object gets destroyed).

    use strict; use Test::More tests=>2; use Scope::Guard; sub try { my @res; my @subs = do { my $g; ( sub { push @res, 'a'; $g = Scope::Guard->new( sub { warn "destroyed"; push @res, 'destroyed' } ); }, sub { push @res, 'b'; undef $g; } ); }; ( shift @subs )->(); is_deeply( \@res, ['a'] ); undef @subs; is_deeply( \@res, [ 'a', 'destroyed' ] ); } try();
Re^4: Reference to guard not released
by dolmen (Sexton) on Jul 19, 2012 at 11:54 UTC
    You are missing the point of what Scope::Guard is. Scope::Guard is not for guarding variables and it does not store any references beside the closure. But the closure does keep references. See my other answer.

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (17)
As of 2014-08-20 14:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (116 votes), past polls