X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FSub%2FDefer.pm;h=236b4a97c0a2c0ae649d8cc2d0b7fdc5ed64e4af;hb=efdff87e4e45cee9e0b2bc5ac2d7659e8870c249;hp=0aa00687728db13cccee9d9c628b35c7c107adf3;hpb=5ef50c4ddcdd784fbc55cd884e37c1d5c39494a9;p=gitmo%2FMoo.git diff --git a/lib/Sub/Defer.pm b/lib/Sub/Defer.pm index 0aa0068..236b4a9 100644 --- a/lib/Sub/Defer.pm +++ b/lib/Sub/Defer.pm @@ -4,6 +4,9 @@ use strictures 1; use base qw(Exporter); use Moo::_Utils; +our $VERSION = '1.003000'; +$VERSION = eval $VERSION; + our @EXPORT = qw(defer_sub undefer_sub); our %DEFERRED; @@ -13,27 +16,45 @@ sub undefer_sub { my ($target, $maker, $undeferred_ref) = @{ $DEFERRED{$deferred}||return $deferred }; + return ${$undeferred_ref} + if ${$undeferred_ref}; ${$undeferred_ref} = my $made = $maker->(); - if (defined($target)) { + + # make sure the method slot has not changed since deferral time + if (defined($target) && $deferred eq *{_getglob($target)}{CODE}||'') { no warnings 'redefine'; + + # I believe $maker already evals with the right package/name, so that + # _install_coderef calls are not necessary --ribasushi *{_getglob($target)} = $made; } + $DEFERRED{$made} = $DEFERRED{$deferred}; + return $made; } +sub defer_info { + my ($deferred) = @_; + $DEFERRED{$deferred||''}; +} + sub defer_sub { my ($target, $maker) = @_; my $undeferred; - my $deferred_string; - my $deferred = sub { - goto &{$undeferred ||= undefer_sub($deferred_string)}; + my $deferred; + $deferred = sub { + $undeferred ||= undefer_sub($deferred); + goto &$undeferred; }; - $deferred_string = "$deferred"; - $DEFERRED{$deferred} = [ $target, $maker, \$undeferred ]; - *{_getglob $target} = $deferred if defined($target); + $DEFERRED{$deferred} = [ $target, $maker, \$undeferred, $deferred ]; + _install_coderef($target => $deferred) if defined $target; return $deferred; } +sub CLONE { + %DEFERRED = map { $_->[3] => $_ } values %DEFERRED; +} + 1; =head1 NAME @@ -78,3 +99,15 @@ If the passed coderef has been L this will "undefer" it. If the passed coderef has not been deferred, this will just return it. If this is confusing, take a look at the example in the L. + +=head1 SUPPORT + +See L for support and contact information. + +=head1 AUTHORS + +See L for authors. + +=head1 COPYRIGHT AND LICENSE + +See L for the copyright and license.