Aspect
view release on metacpan or search on metacpan
lib/Aspect/Advice/After.pm view on Meta::CPAN
package Aspect::Advice::After;
use strict;
# Added by eilara as hack around caller() core dump
# NOTE: Now we've switched to Sub::Uplevel can this be removed? --ADAMK
use Carp::Heavy ();
use Carp ();
use Sub::Uplevel ();
use Aspect::Hook ();
use Aspect::Advice ();
use Aspect::Point ();
our $VERSION = '1.04';
our @ISA = 'Aspect::Advice';
# NOTE: To simplify debugging of the generated code, all injected string
# fragments will be defined in $UPPERCASE, and all lexical variables to be
# accessed via the closure will be in $lowercase.
sub _install {
my $self = shift;
my $pointcut = $self->pointcut;
my $code = $self->code;
my $lexical = $self->lexical;
# Get the curried version of the pointcut we will use for the
# runtime checks instead of the original.
# Because $MATCH_RUN is used in boolean conditionals, if there
# is nothing to do the compiler will optimise away the code entirely.
my $curried = $pointcut->curry_runtime;
my $compiled = $curried ? $curried->compiled_runtime : undef;
my $MATCH_RUN = $compiled ? '$compiled->()' : 1;
# When an aspect falls out of scope, we don't attempt to remove
# the generated hook code, because it might (for reasons potentially
# outside our control) have been recursively hooked several times
# by both Aspect and other modules.
# Instead, we store an "out of scope" flag that is used to shortcut
# past the hook as quickely as possible.
# This flag is shared between all the generated hooks for each
# installed Aspect.
# If the advice is going to last lexical then we don't need to
# check or use the $out_of_scope variable.
my $out_of_scope = undef;
my $MATCH_DISABLED = $lexical ? '$out_of_scope' : '0';
# Find all pointcuts that are statically matched
# wrap the method with advice code and install the wrapper
foreach my $name ( $pointcut->match_all ) {
my $NAME = $name; # For completeness
no strict 'refs';
my $original = *$name{CODE};
unless ( $original ) {
Carp::croak("Can't wrap non-existent subroutine ", $name);
}
# Any way to set prototypes other than eval?
my $PROTOTYPE = prototype($original);
$PROTOTYPE = defined($PROTOTYPE) ? "($PROTOTYPE)" : '';
# Generate the new function
no warnings 'redefine';
eval <<"END_PERL"; die $@ if $@;
package Aspect::Hook;
( run in 0.585 second using v1.01-cache-2.11-cpan-98e64b0badf )