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

NAME

Aspect-Oriented Perl - Aspect-oriented programming in pure Perl

DESCRIPTION

Introduction to AOP

Aspect-oriented Programming (AOP) is a programming methodology developed by Xerox PARC. The basic idea is that in complex class systems there are certain aspects or behaviors that cannot normally be expressed in a coherent, concise and precise way. One example of such aspects are design patterns, which combine various kinds of classes to produce a common type of behavior.

Another such aspect concerns debugging or tracing the flow of execution. Maybe every time one of a set of subroutines is entered or exited, you want to want to print a line telling you so. Normally you would you the good old 'print' statement debugger, or maybe you would actually use a custom Perl debugger or a Devel::* module. But what if the profile produces too much output you're not actually interested in? And a custom debugger usually does not make for reusable, easily customizable code.

You might change the source of all those subroutines you're interested in to print the desired information. When you are done debugging, you remove the print statements again. That's a lot of effort and can lead to bugs and oversights of its own. Furthermore, your code is littered with unsightly print statements. If you want to change the output, you have to change every print statement. If you add a class, remember to add the print statements. It's a mess. Wouldn't it be easier if you could influence the behavior of those subroutines from the outside, like a switch you could flip to make them print a statement when they're entered (in a consistent way, without chance of forgetting to create or remove a print statement), then flip the switch again to turn that behavior off?

That's what aspect-oriented programming is about. Aspects usually concern many classes right across the class hierarchy. One says that they "crosscut the program structure" and refers to them as "crosscutting concerns".

Just like object-oriented programming (OOP) encapsulates the concepts and functionality of individual classes and arranges them in a class hierarchy, so does AOP encapsulate the concerns of many classes and make those aspects or behvaviors reusable. In this way AOP is orthogonal to OOP.

Aspects allow you to change the interaction of objects without breaking their encapsulation. You don't change the behaviors of the objects per se, but rather the way they behave at the seams, at well-defined points during execution. For example, you can intercept method calls, override methods, influence operators, and generally influence the flow of execution in a way that isn't possible without AOP.

Certainly you can achieve all these things without AOP, but it would be a lot harder, less (or, more likely, not at all) reusable and more error-prone. Just as you can simulate any object-oriented program using non-OO techniques, but OO makes things just so much easier.

In a way, aspects do break encapsulation as they influence behavior in places they might not be supposed to. But these modifications happen in a very controlled environment; furthermore it could be argued that aspects are part of objects; just not of a single object, but a whole range of objects, possibily all of them, depending on the individual aspect.

Note that aspects don't depend on OOP; it's perfectly possible to use AOP in non-OO programs.

In terms of units of modularity, aspects are on-par with objects. Indeed, aspects can themselves be expressed as objects, so they can be subclassed and further reused.

Special consideration must be given to the overlapping and interaction of aspects.

Some more things that AOP can do to whet your appetite: Aspects can implement design patterns using code, so you don't have to modify classes that might play different roles in different design patterns, but simply determine those roles from outside, using aspects. As such, aspects don't just play a role in the implementation phase of your project, but in the planning phase as well.

Aspects can also unify error-handling and logging across the class hierarchy in a completely flexible way; if you want to change the logging behavior of all those classes, you do it in one central point instead of many points throughout the classes.

By modularizing such concerns into aspects you ensure consistent behavior across your project and don't depend on individual programmers to follow a convention, say, on how to write security or error checking. Indeed, it may not be necessary to for individual programmers to write code for such concerns at all, if they're centrally managed, from the outside, as it is, by aspects.

Aspects promise fewer bugs in your code and faster development of your project.

Aspects in Perl

The goal of aspect-oriented Perl (AOPerl) is to provide an efficient and flexible implementation of aspect-oriented programming worthy of Perl. AOPerl should make aspects simple and portable. There will be a supporting web site, tutorials, examples and talks at conferences.

Thanks to the dynamic nature of Perl, aspects can happen at runtime. They can also be disabled and enabled at runtime. Aspects are simply implemented as Perl classes and modules and need no change at the language or interpreter level. They are not source filters and are therefore more flexible than other implementations of aspect-oriented programming, such as AspectJ.

Performance

We now come to the question of performance impact. This isn't a straightforward answer, as there is no benchmark suite so far; furthermore we need to measure the use of aspects against hand-coding the same functionality. Once the aspects are set up (which happens at run-time, so it will at least delay the actual start of your program) the performance impact should be minimal, since we are effectively doing a few more subroutine calls. Aspects that affect variables as well as subroutines are a different matter, since those variables are tied behind the scenes, so the performance impact of tying variables is incurred.

However, this functionality would have had to be added manually anyway, and developing time is often a factor as well; sometimes even more important than execution time.

It is conceivable that in a future version, certain static aspects (i.e. ones that are effectively enabled at compile time and that don't change at run-time and only affect source over which you have complete control) could be turned into a preprocessor that could even do some optimizations on the generated source code.

Terminology

The module closely follows AspectJ's idea of aspects. That is, there are

Join Point

A well-defined point of execution such as entering a sub or exiting a sub.

Pointcut

A pointcut is an expression on a set of join points. Pointcuts can themselves be combined to form other pointcuts.

Advice

Code associated with a pointcut, to be executed when that pointcut is matched in the course of execution.

Implementation Details

We distinguish between two phases in the lifetime of an aspect: define time and run time. Aspect define time happens when an advice object is set up to connect advice code with a pointcut. Aspect run time happens during the program's run time, when the advice handlers are called. Define time also happens during the program's run time.

Aspects are translated into precalls, postcalls and ties behind the scenes. When an aspect is disabled, its advice handlers are uninstalled, so the original subroutines look pristine and don't incur any performance hit.

References

Aspect-oriented Software Development

http://aosd.net/

AspectJ

http://aspectj.org

"Untangling Code",

http://www.technologyreview.com/magazine/jan01/TR10_kiczales.asp

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

Aspect::Ideas(3pm), Aspect(3pm).