Aspect
view release on metacpan or search on metacpan
For these reasons, the usage of multiple highest declarators such as in
the following example is not support, and so the following will throw an
exception.
before {
print "This advice will not compile\n";
} wantscalar & (
(call 'My::foo' & highest)
|
(call 'My::bar' & highest)
);
This limitation may change in future releases. Feedback welcome.
For more information on the "highest" pointcut see
Aspect::Pointcut::Highest.
throwing
my $string = throwing qr/does not exist/;
my $object = throwing 'Exception::Class';
The "throwing" pointcut is used with the "after" to restrict the
pointcut so advice code is only fired for a specific die message or a
particular exception class (or subclass).
The "throwing" declarator takes a single parameter which is the pointcut
spec, and can be provided in two different forms.
regexp
If a regular expression is passed to "throwing" it will be matched
against the exception if and only if the exception is a plain string.
Thus, the regexp form can be used to trap unstructured errors emitted by
"die" or "croak" while NOT trapping any formal exception objects of any
kind.
string
If a string is passed to "throwing" it will be treated as a class name
and will be matched against the exception via an "isa" method call if
and only if the exception is an object.
Thus, the string form can be used to trap and handle specific types of
exceptions while allowing other types of exceptions or raw string errors
to pass through.
For more information on the "throwing" pointcut see
Aspect::Pointcut::Throwing.
returning
after {
print "No exception\n";
} call 'Foo::bar' & returning;
The "returning" pointcut is used with "after" advice types to indicate
the join point should only occur when a function is returning without
throwing an exception.
true
# Intercept an adjustable random percentage of calls to a function
our $RATE = 0.01;
before {
print "The few, the brave, the 1%\n";
} call 'My::foo'
& true {
rand() < $RATE
};
Because of the lengths that Aspect goes to internally to optimise the
selection and interception of calls, writing your own custom pointcuts
can be very difficult.
When a custom or unusual pattern of interception is needed, often all
that is desired is to extend a relatively normal pointcut with an extra
caveat.
To allow for this scenario, Aspect provides the "true" pointcut.
This pointcut allows you to specify any arbitrary code to match on. This
code will be executed at run-time if the join point matches all previous
conditions.
The join point matches if the function or closure returns true, and does
not match if the code returns false or nothing at all.
before
before {
# Don't call the function, return instead
$_->return_value(1);
} call 'My::foo';
The before advice declaration is used to defined advice code that will
be run instead of the code originally at the join points, but continuing
on to the real function if no action is taken to say otherwise.
When called in void context, as shown above, "before" will install the
advice permanently into your program.
When called in scalar context, as shown below, "before" will return a
guard object and enable the advice for as long as that guard object
continues to remain in scope or otherwise avoid being destroyed.
SCOPE: {
my $guard = before {
print "Hello World!\n";
} call 'My::foo';
# This will print
My::foo();
}
# This will NOT print
My::foo();
Because the end result of the code at the join points is irrelevant to
this type of advice and the Aspect system does not need to hang around
and maintain control during the join point, the underlying
implementation is done in a way that is by far the fastest and with the
least impact (essentially none) on the execution of your program.
( run in 1.016 second using v1.01-cache-2.11-cpan-39bf76dae61 )