X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FSub-Op.git;a=blobdiff_plain;f=lib%2FSub%2FOp.pm;h=8c8f6c87a4df667033ccba09f8a57db8b118221f;hp=76d22dacb4dab4ba36869b65ecbceaf8353ffae7;hb=5ae3324ff295015e051249ded13b2353ee8af258;hpb=cd64aa350186e54b47e313c566e5915f5aeddce9 diff --git a/lib/Sub/Op.pm b/lib/Sub/Op.pm index 76d22da..8c8f6c8 100644 --- a/lib/Sub/Op.pm +++ b/lib/Sub/Op.pm @@ -118,6 +118,8 @@ When L and L are loaded, they get automatically monkeypatched so =cut +use Scalar::Util; + use B::Hooks::EndOfScope; use Variable::Magic 0.08; @@ -147,6 +149,16 @@ my $sw = Variable::Magic::wizard( }, ); +sub _tag { + my ($pkg, $name) = @_; + + my $fqn = join '::', $pkg, $name; + + return { + proto => prototype($fqn), + }; +} + sub _map { my ($pkg) = @_; @@ -161,8 +173,14 @@ sub _map { sub _cast { my ($pkg, $name) = @_; - no strict 'refs'; - Variable::Magic::cast(%{"${pkg}::"}, $sw, $pkg, { $name => 1 }); + my $map = { $name => _tag(@_) }; + + { + no strict 'refs'; + Variable::Magic::cast(%{"${pkg}::"}, $sw, $pkg, $map); + } + + return $map; } sub _dispell { @@ -245,9 +263,15 @@ sub enable { my $map = _map($pkg); if (defined $map) { - $map->{$name} = 1; + $map->{$name} = _tag($pkg, $name); } else { - _cast($pkg, $name); + $map = _cast($pkg, $name); + } + + my $proto = $map->{$name}->{proto}; + if (defined $proto) { + no strict 'refs'; + Scalar::Util::set_prototype(\&{"${pkg}::$name"}, undef); } $^H |= 0x00020000; @@ -273,6 +297,12 @@ sub disable { my $map = _map($pkg); if (defined $map) { + my $proto = $map->{$name}->{proto}; + if (defined $proto) { + no strict 'refs'; + Scalar::Util::set_prototype(\&{"${pkg}::$name"}, $proto); + } + delete $map->{$name}; unless (keys %$map) { _dispell($pkg);