The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Aspect - Even more rope to hang yourself

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 type Aspect::PointCut (or a subclass thereof). If the first argument is no such object, it will be passed to calls(), 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 package main. It then sets up advice on that join point that prints a short nice every time the foo() 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 the Aspect::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 with qr//) 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 package main only.

calls(qr/^(.*::)?[gs]et_/)

constructs a pointcut that matches the call join point of all subroutines whose name starts with get_ or set_, 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 with bar.

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 type Aspect::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 logical or. 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 as

  calls(qr/./) | returns(qr/./)
and_op(leftexpr, rightexpr)

This function is like or_op, except that the two subexpressions are combined in a logical and. 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 type Aspect::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 the Foo package or any other package that starts with Foo::.

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 Grünauer <marcel@cpan.org>

COPYRIGHT

Copyright 2001-2002 Marcel Grünauer. 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).