Aspect::Pointcut::Cflow - Cflow pointcut


Aspect documentation Contained in the Aspect distribution.

Index


Code Index:

NAME

Top

Aspect::Pointcut::Cflow - Cflow pointcut

SYNOPSIS

Top

  Aspect::Pointcut::Cflow->new;

DESCRIPTION

Top

None yet.

AUTHORS

Top

Adam Kennedy <adamk@cpan.org>

Marcel Grünauer <marcel@cpan.org>

Ran Eilam <eilara@cpan.org>

COPYRIGHT

Top


Aspect documentation Contained in the Aspect distribution.

package Aspect::Pointcut::Cflow;

use strict;
use warnings;
use Carp                   ();
use Params::Util           ();
use Aspect::Pointcut       ();
use Aspect::Pointcut::Call ();
use Aspect::Point::Static  ();

our $VERSION = '1.01';
our @ISA     = 'Aspect::Pointcut';

use constant KEY  => 0;
use constant SPEC => 2;





######################################################################
# Constructor Methods

sub new {
	my $class = shift;

	# Check and default the cflow key
	my $key = @_ > 1 ? shift : 'enclosing';
	unless ( Params::Util::_IDENTIFIER($key) ) {
		Carp::croak('Invalid runtime context key');
	}

	# Generate it via call
	my $call = Aspect::Pointcut::Call->new(shift);
	return bless [ $key, @$call ], $class;
}





######################################################################
# Weaving Methods

# The cflow pointcut is currently of no value at weave time, because it is
# actually implemented as something closer to cflowbelow.
sub curry_weave {
	return;
}

# The cflow pointcuts do not curry at all.
# So they don't need to clone, and can be used directly.
sub curry_runtime {
	return $_[0];
}





######################################################################
# Runtime Methods

sub compile_runtime {
	my $self = shift;
	return sub {
		my $level   = 2;
		my $caller  = undef;
		while ( my $cc = caller_info($level++) ) {
			next unless $self->[SPEC]->( $cc->{sub_name} );
			$caller = $cc;
			last;
		}
		return 0 unless $caller;
		my $static = bless {
			sub_name => $caller->{sub_name},
			pointcut => $Aspect::POINT->{pointcut},
			args     => $caller->{args},
		}, 'Aspect::Point::Static';
		$Aspect::POINT->{$self->[KEY]} = $static;
		return 1;
	};
}

sub caller_info {
	my $level = shift;

	package DB;

	my %call_info;
	@call_info{ qw(
		calling_package
		sub_name
		has_params
	) } = (CORE::caller($level))[0, 3, 4];

	return defined $call_info{calling_package}
		? {
			%call_info,
			args => [
				$call_info{has_params} ? @DB::args : ()
			],
		} : 0;
}

1;

__END__