Overview - Aspects in Perl
There isn't much in the way of documentaton, since at the moment I'm just toying around with ideas. I read about aspects on Xerox Parc's page and at aspectj.org and thought about how to implement aspects in Perl. The problem is, to do that effectively, you need support from the language and the compiler.
So I attempted a naive implementation, a proof-of-concept. Perl is hugely dynamic, everything's up for grabs. Including the flow of execution, if you use the Perl debugger API. So the idea is to hijack the debugger and 'make it do' aspects. Sure, this slows down things, but again, performance is not a consideration at this point. With Perl 6 still in the planning stadium, if aspects work and people like it, maybe it can at some point be made a part of the language itself.
The module closely follows AspectJ's idea of aspects. That is, there are
To see how it all fits together, get the development version via CVS. You need Perl 5.6 for this to work. I've developed and tested it on Linux, so I can't guarantee if it works on other platforms, especially Windows. But so long as the Perl debugger works on a platform, it should be ok.
The module docs themselves are outdated, but go to the examples/
directory and run pointcut.pl
, which will show you how it all works
(from the outside).
A few words about the inner working: When using the Perl debugger,
you get a chance to intercept subroutine calls via the DB::sub()
subroutine. So there are two join points here already: a call join point
occurs before executing the subroutine, and a return join point occurs
afterwards. Now you might want something to happen when a subroutine
main::mysub()
is entered. To do so, you use calls()
to define a
pointcut using a call join point that matches if the name of the current
sub is main::mysub()
. Using advice()
, you associate the code you
want to execute when the pointcut matches.
All this is a bit abstract, so I suggest you look at
examples/pointcut.pl
, and follow the execution path into Aspect.pm
(to set things up), the Pointcut modules (to define various types of
and operations on pointcuts), and Devel/Aspect.pm
(which does all
the hard work of testing all defined pointcuts whenever a sub is entered
or exited).
It is precisely this constant testing that slows things down (apart from
the overhead of the Perl debugger itself); I've heard AspectJ implements
this differently to avoid the overhead (some sort of preprocessing,
supposedly). On the other hand, since Perl aspects are evaluated at
runtime, it is conceivable that they can be changed at runtime (no
idea why someone would want that, but that's what they thought about
Quantum::Superpositions
as well...).
In pointcut.pl
, advice is defined explicitly, but later I want
to define sets of advice (which will make up an 'aspect') in Perl
modules that, when use()
'd, produce the desired behavior. One
idea is to force objects to be singletons by intercepting calls to its
constructor. Or you can implement memoization (caching subroutine results,
cf. Memoize.pm
). Access control is another idea for an aspect that
could be modularized.
Hopefully this has made it a little clearer as to what's going on; any comments or ideas are welcome.