Aspect

 view release on metacpan or  search on metacpan

lib/Aspect.pm  view on Meta::CPAN


  my $string = throwing qr/does not exist/;
  my $object = throwing 'Exception::Class';

The C<throwing> pointcut is used with the C<after> to restrict the pointcut so
advice code is only fired for a specific die message or a particular exception
class (or subclass).

The C<throwing> declarator takes a single parameter which is the pointcut spec,
and can be provided in two different forms.

B<regexp>

If a regular expression is passed to C<throwing> it will be matched against
the exception if and only if the exception is a plain string.

Thus, the regexp form can be used to trap unstructured errors emitted by C<die>
or C<croak> while B<NOT> trapping any formal exception objects of any kind.

B<string>

If a string is passed to C<throwing> it will be treated as a class name and
will be matched against the exception via an C<isa> method call if and only
if the exception is an object.

Thus, the string form can be used to trap and handle specific types of
exceptions while allowing other types of exceptions or raw string errors to
pass through.

For more information on the C<throwing> pointcut see
L<Aspect::Pointcut::Throwing>.

=cut

sub throwing (;$) {
	Aspect::Pointcut::Throwing->new(@_);
}

=pod

=head2 returning

  after {
      print "No exception\n";
  } call 'Foo::bar' & returning;

The C<returning> pointcut is used with C<after> advice types to indicate the
join point should only occur when a function is returning B<without> throwing
an exception.

=cut

sub returning () {
	Aspect::Pointcut::Returning->new;
}

=pod

=head2 true

  # Intercept an adjustable random percentage of calls to a function
  our $RATE = 0.01;
  
  before {
      print "The few, the brave, the 1%\n";
  } call 'My::foo'
  & true {
      rand() < $RATE
  };

Because of the lengths that B<Aspect> goes to internally to optimise the
selection and interception of calls, writing your own custom pointcuts can
be very difficult.

When a custom or unusual pattern of interception is needed, often all that is
desired is to extend a relatively normal pointcut with an extra caveat.

To allow for this scenario, B<Aspect> provides the C<true> pointcut.

This pointcut allows you to specify any arbitrary code to match on. This code
will be executed at run-time if the join point matches all previous conditions.

The join point matches if the function or closure returns true, and does not
match if the code returns false or nothing at all.

=cut

sub true (&) {
	Aspect::Pointcut::True->new(@_);
}

=pod

=head2 before

  before {
      # Don't call the function, return instead
      $_->return_value(1);
  } call 'My::foo';

The B<before> advice declaration is used to defined advice code that will be
run instead of the code originally at the join points, but continuing on to the
real function if no action is taken to say otherwise.

When called in void context, as shown above, C<before> will install the advice
permanently into your program.

When called in scalar context, as shown below, C<before> will return a guard
object and enable the advice for as long as that guard object continues to
remain in scope or otherwise avoid being destroyed.

  SCOPE: {
      my $guard = before {
          print "Hello World!\n";
      } call 'My::foo';
  
      # This will print
      My::foo(); 
  }
  
  # This will NOT print



( run in 2.391 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )