Re: [perl #75792] Unexpected nested closure circular reference (possibly a Scalar::Util::weaken issue?)
[email protected] (Dave Mitchell)
| Newsgroups | perl.perl5.porters |
|---|---|
| Message-ID | <[email protected]> |
On Wed, Jun 16, 2010 at 02:28:10AM -0700, Peter Rabbitson wrote:
> This leaks $self (and everything below)
> ========================================
> sub closure_factory {
> my $self = {};
>
> sub {
> my $weakself = $self;
> weaken $weakself;
> $self->{coderef} = sub { die $weakself if $weakself };
> }->();
>
> $self;
> }
The inner anon sub maintains a reference to the outer anon sub, so as long
as the inner one lives, so does the outer (this is the way perl does
things internally). The outer one has captured $self, which is a full fat
reference to the hash that holds a ref to the inner sub - hence a
reference loop.
So, not a bug.
The following example code avoids it; possibly something similar may
work for your real-life code:
sub closure_factory {
my $self = {};
sub {
my $weakself = $_[0];
weaken $weakself;
$weakself->{coderef} = sub { die $weakself if $weakself };
}->($self);
$self;
}
--
My Dad used to say 'always fight fire with fire', which is probably why
he got thrown out of the fire brigade.