NAME
Aspect - Convenience functions to set up aspects
SYNOPSIS
use Aspect qw(advice calls returns);
sub get_foo { ... }
sub set_bar { ... }
my $spec = qr/^(.*::)?[gs]et_/;
$aspect = advice(calls($spec) | returns($spec), sub { ... });
$aspect->enable;
DESCRIPTION
For general information on aspect-oriented programming in Perl, read Aspect::Intro
, Aspect::Overview
, Aspect::Cookbook
and Aspect::Ideas
.
This module exports convenience functions that make setting up aspects easier. It is perfectly possible to create pointcuts and aspects without these functions, but you would have to call the relevant constructors and methods manually.
EXPORT
None by default.
EXPORT_OK
advice(pointcut, code)
-
This function takes two arguments and creates an
Aspect::Advice
object. The first argument is a pointcut expression, which can be an object of the typeAspect::PointCut
(or a subclass thereof). If the first argument is no such object, it will be passed tocalls()
, which is the most common type of pointcut.The second parameter is the advice code. This is a coderef that will be installed on join points matching the pointcut expression.
For example,
my $pointcut = calls('main::foo'); my $aspect = advice($pointcut, sub { print "called foo()\n" });
first creates a pointcut that matches the call join point on the sub
foo()
in the packagemain
. It then sets up advice on that join point that prints a short nice every time thefoo()
function is called.The same effect can be achieved with
my $aspect = advice('main::foo', sub { print "called foo()\n" });
Note that this function creates the aspect, but does not enable it. To do so, you have to call
enable()
on the returned object. See theAspect::Advice
manpage for details. calls(specifier)
-
This function, or rather, pointcut operator, constructs an object of the type
Aspect::PointCut::Calls
. This pointcut matches all call join points whose subroutine name correspond to the specifier given as the argument. The specifier can be a plain string, in which case only that specific subroutine matches, or a regular expression (probably constructed withqr//
) that is used to match the subroutine name, or a code reference that is given each potential subroutine name in turn and is expected to return a true value if the corresponding call join point is supposed to match. The subroutine names are fully qualified with their package names when comparing them with the specifier.Examples:
calls('main::y1')
-
constructs a pointcut that matches the call join point of sub
y1
in packagemain
only. calls(qr/^(.*::)?[gs]et_/)
-
constructs a pointcut that matches the call join point of all subroutines whose name starts with
get_
orset_
, in any package. calls(sub { local $_ = shift; /^Foo/ && /bar$/ })
-
constructs a pointcut that matches the call join point of all subroutines whose fully qualified name starts with
Foo
and ends withbar
.
returns(specifier)
-
This function, or pointcut operator, is just like
calls()
, except that it applies to return join points instead of call join points. The object it constructs is of the typeAspect::PointCut::Returns
. around(specifier)
-
This function creates a pointcut that applies to call join points as well as return join points. It is equivalent to
calls(specifier) | returns(specifier)
. or_op(leftexpr, rightexpr)
-
This function constructs an object of the type
Aspect::PointCut::OrOp
and takes two pointcut expressions as arguments. When checking to see whether a particular join point matches (e.g., when enabling an aspect), the results of both left and right expressions are combined using logicalor
. That is, the whole pointcut expression matches if the left expression or the right expression matches.Example:
or_op(calls(qr/./), returns(qr/./))
matches both the call join point and the return join point of every subroutine in every package.
This function is overloaded so you can use the
|
operator instead. So the above example could be rewritten ascalls(qr/./) | returns(qr/./)
and_op(leftexpr, rightexpr)
-
This function is like
or_op
, except that the two subexpressions are combined in a logicaland
. You can use the overloaded operator&
instead. So the whole pointcut expression match a join point only if both subexpression match. The constructed object is of the typeAspect::PointCut::AndOp
. not_op(expr)
-
This function constructs an object of the type
Aspect::PointCut::NotOp
. This pointcut matches a join point only if the argument's pointcut expression does not match it. You can use the overloaded operator!
instead. For example,calls(qr/./) & !calls(qr/^Foo::/)
matches every call join point whose corresponding subroutine is not in theFoo
package or any other package that starts withFoo::
.
EXPORT_TAGS
Using :all
you can import all of the above functions.
BUGS
None known so far. If you find any bugs or oddities, please do inform the author.
AUTHOR
Marcel Grunauer, <marcel@codewerk.com>
COPYRIGHT
Copyright 2001 Marcel Grunauer. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
SEE ALSO
perl(1), Aspect::Intro(3pm), Aspect::Overview(3pm).