=head1 NAME

Aspect Ideas - new ideas for aspects-oriented Perl

=head1 DESCRIPTION

=head1 Distribution Ideas

=over 4

=item Cookbook recipes

=item Benchmark suite

=item Comprehensive tests

=back

The following sections outline ideas for modular aspects, for new
types of join points, and for new types of pointcuts. There are
also some general ideas.

=head1 Modular Aspect Ideas

=over 4

=item Development Aspects

Development aspects are aspects that are useful in the development
of software. Because aspect behavior can be enabled and disabled
easily, you can cleanly separate the product from the development
aids. When you are finished, you can remove the aspects altogether
leaving only the product. That way, the development tools are not
included in the finished product, but can easily be reenabled for
further development.

An obvious example of a development aspect is tracing the program
flow. See C<Aspect::Trace>.

=item Design-by-contract

Implement design-by-contract pre- and postconditions using aspects,
cf. C<Class::Contract>.

=item Default Variable I/O

Per Sub::Underscore.

This sets up a wrapper for a sub that takes a scalar as an argument and
returns a scalar. The wrapper calls the sub with C<$_> if no argument
was given and puts the return value in C<$_> if the sub was called in
void context.

An example:

    my $aspect = Aspect::UnderscoreContext->new('main::plus1');
    $aspect->enable;
    ...
    sub plus1 { $_[0] + 1 };
    plus1;  # now $_ has been incremented

=item Package Redirection

say you implemented a specialized version of the HTTP::Request
object and want LWP to use that. But you don't want to change the
LWP code, as that would mean branching. And sending a patch to
Gisle isn't a good idea either, because your new class is very
specialized, so the patch might get rejected. So you set up advice
that any calls to package HTTP::Request should be redirected to
your new class.

=item Load-balancing

have the same code run on different boxes or in different processes
or threads and provide mod_backhand-like functionality via aspects.

=item Advertising

A stupid use of include join points:

    advice(includes(qr/./, \&aspect_ad))

might say "Thank you for using CGI.pm" (get the module name via
context) or "Brought to you by Aspects".

Automatically done only once per module, as each module is use()d
only once, but do that with op join points as well: print an ad
the first time only via $seen{$op}++.

=item Testing

Aspects useful for CPANTS

=item Timeout

Aspect to provide timeout to subs via alarm().

=item Tainting

Aspect to taint and untaint args and return values of subroutines.

=item Authentication Aspect

Users and groups; give rwx access to variables and subroutines.
Via aspects, you have external control over permissions. When doing
something that requires permission, either ask for authorization
(provided by a keychain?) or allow or deny, like Apache does.

=item Once-only Aspects

Run the advice code once, then remove the aspect code.

=item Aspects checking arguments

An aspect could check the bounds of subroutine arguments and, if
necessary, throw an exception or otherwise signal an error.

=back




=head1 Join Point Ideas

Some ideas for new kinds of join points, that is, well-defined
points during execution:

=over 4

=item Include Join Point

Using coderef-in-@INC, you can intercept use() statements:

	BEGIN { unshift @INC, \&include_join_point }
	sub include_join_point {
		# process relevant advice
		# now decline so normal include handlers
		# can do their work

	}

=item Op Join Points

overload operations to raise op join points, e.g.:

	overload '+' => \&add_join_point;

	sub add_join_point {
		# process relevant advice
		# return a+b as normal
	}

This won't work if the package already overloads operations.

=item Import Join Points

by overriding or wrapping a package's import()

=item Destroy Join Points

by overriding or wrapping a package's DESTROY()

=item Phasic Join Points

by defining a BEGIN, INIT, CHECK, END handler for a package

=item Package-specfic Join Points

Packages (modules, classes) may define their own types of join
points. For example, the Error module might define a Throw Join
Point, a Catches Join Point, a Try Join Point and a Finally Join
Point.

Classes that construct other classes (such as Class::MethodMaker
or Class::Contract) could define a Field Get Join Point, a Field
Set Join Point and a Constructor Join Point. A convenience Field
Access Join Point could simply be defined as "either a Field Get
Join Point or a Field Set Join Point". And there might be a Method
Call Join Point and a Method Return Join Points. These class-related
join points would also come in useful in Perl 6, which has special
language support for classes (as opposed to non-OO modules).

These special join points must be able to influence the context
passed to the advice code. For example, a Field Set Join Point
would want to pass on the new value in the context (though in this
case it can be gleaned by looking at the method's arguments).

Viewed this way, Perl signal handlers could be viewed as advice on
Signal Join Points.

=back




=head1 Pointcut Ideas

=over 4

=item New pointcut designators

Using existing pointcut operators and logical operators you can
create new pointcut designators.

=item Pointcut match efficiency

    pointcut p1 { $joinpt1 & $joinpt2 }
    pointcut p2 { $joinpt3 && $joinpt4 }
    pointcut p3 { $p1 | $p2 }

Cache eval results for join points and points cuts, so (as is the
case with p3 above) each join point and pointcut is eval'd only
once per advice.

=item C<cflow($x)>

cflow() is a pointcut operator that matches any kind of join point
where the call stack at run time matches the condition specified
with the cflow() operator.

=item C<pkg($x)>

matches join points of any kind (i.e., context isn't checked)
where the currently executing package matches C<$x>.

=item C<is_a($x)>

matches join points of any kind (i.e., context isn't checked)
where the currently executing package is-a (per Perl's C<@ISA> hierarchy)
C<$x>.

=item C<calledby($x)>

is like C<cflow()> but looks at the direct caller
only. That is, there is a match if the current sub's immediate caller
matches C<$x>.

=back




=head1 Debugger Support

Debugger support for developing with aspects.

=over 4

=item Debugger commands

Continue to next join point

=item Affected Join Points

List all join points affected by a pointcut.

=item Meta-aspects

An aspect to insert breakpoints or print other information when a
join point is encountered.

=back




=head1 Completely Random Ideas

Runtime (RT), coincides with program runtime. Define-time (DT),
also happens at program runtime.

At DT, i.e., when an advice is defined, the advice's pointcut is
tested against each join point in the program. If a join point
matches the pointcut, an advice handler is installed. The pointcut
is represented as an abstract syntax tree (AST). The AST's match_define
method is called for each join point.

The advice handlers become part of the normal program flow. Advice
handlers execute the advice code under different circumstances for
different types of pointcut operators. Each pointcut operator has,
alongside the DT test (match_define), also a RT test (match_run).

For a calls() pointcut operator, the test always evaluates to true:
Since it only matches call join points at DT then once it's installed,
the code runs. There is no further condition.

For a cflow() pointcut operator, a DT match doesn't mean that the
advice code will run all the time; it will only run if the RT
control flow matches the cflow() argument.

Example:

  advice( calls('get') && cflow(qr/^Graphics/), sub { ... } )

means the following: at DT, calls() matches call join points where
the sub name is 'get', and cflow() matches any join point, i.e.
its match_define is always true. At RT, the pointcut expression is
evaluated again, using the same AST as was constructed at DT, but
this time with run time tests (i.e., using match_run): calls()
always matches since it's installed, but cflow() matches only if
caller() at some point matches /^Graphics/; and because of '&&',
both RT tests must be true. If the pointcut expression matches,
the advice code runs.

Like httpd is a web server, AOP can be seen as a server, where
there are several phases during which aspects can change things in
the program's flow.

Aspect order: if several aspects' pointcut affect a given join
point, then the advice code of the aspect that has been defined
later is run first.

Implement design patterns (cf. GoF). Make patterns first-class
citizens.

Separation of concerns: separate the basic algorithms from
special-purpose concerns such as synchronization, real-time
constraints, and location control.

Use Aspects where they make sense; don't use them where they don't
make sense. Like with OOP and Perl.

Combine aspects with other Perl technology: quantum aspects, aspects
and coroutines, aspects and attributes, aspects and threads, aspects
during compilation (B::*; compile-time join points; insert potential
advice handlers during opportune moments, e.g. at the beginning
and end of loops, after variable assignments etc.)

"Dynamic extension of class structure for duration of a task.  This
removes the pollution of the class graph with information which is
only needed for a specific task." --
http://www.ccs.neu.edu/research/demeter/biblio/context.html

=head1 Possible Publicity

=over 4

=item Aspect-related sites

=item Perl monger mailing lists

=item use.perl journal

=item articles

In online and offline magazines (perl.com, tpj, consumer mags).

=item Search engines and directories

=item aspect.perl.org -> aspect.unixbeard.net ?

=item lists.perl.org

entry for the perl-aspects mailing list.

=item conference talks

=item AOP conferences

Check AOSD 2002: http://trese.cs.utwente.nl/aosd2002.htm.

=back

=head1 AUTHOR

Marcel GrE<uuml>nauer <marcel.gruenauer@chello.at>

=head1 COPYRIGHT

Copyright 2001 Marcel GrE<uuml>nauer. All rights reserved.

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=head1 SEE ALSO

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

=cut
