From: Graham Knop Date: Thu, 25 Jul 2013 14:39:00 +0000 (-0400) Subject: stop leaking memory for deferred subs X-Git-Tag: v1.003001~28 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c86c182d6a07287f428fa4edca7c05fae95a8830;p=gitmo%2FMoo.git stop leaking memory for deferred subs --- diff --git a/lib/Sub/Defer.pm b/lib/Sub/Defer.pm index 236b4a9..5044ab7 100644 --- a/lib/Sub/Defer.pm +++ b/lib/Sub/Defer.pm @@ -3,6 +3,7 @@ package Sub::Defer; use strictures 1; use base qw(Exporter); use Moo::_Utils; +use Scalar::Util qw(weaken); our $VERSION = '1.003000'; $VERSION = eval $VERSION; @@ -28,7 +29,7 @@ sub undefer_sub { # _install_coderef calls are not necessary --ribasushi *{_getglob($target)} = $made; } - $DEFERRED{$made} = $DEFERRED{$deferred}; + weaken($DEFERRED{$made} = $DEFERRED{$deferred}); return $made; } @@ -41,18 +42,20 @@ sub defer_info { sub defer_sub { my ($target, $maker) = @_; my $undeferred; - my $deferred; - $deferred = sub { - $undeferred ||= undefer_sub($deferred); + my $deferred_info; + my $deferred = sub { + $undeferred ||= undefer_sub($deferred_info->[3]); goto &$undeferred; }; - $DEFERRED{$deferred} = [ $target, $maker, \$undeferred, $deferred ]; + $deferred_info = [ $target, $maker, \$undeferred, $deferred ]; + weaken($DEFERRED{$deferred} = $deferred_info); _install_coderef($target => $deferred) if defined $target; return $deferred; } sub CLONE { - %DEFERRED = map { $_->[3] => $_ } values %DEFERRED; + %DEFERRED = map { defined $_ ? ($_->[3] => $_) : () } values %DEFERRED; + weaken($_) for values %DEFERRED; } 1;