File Coverage

blib/lib/Aspect/Point/Functions.pm
Criterion Covered Total %
statement 34 56 60.7
branch 12 26 46.1
condition n/a
subroutine 7 17 41.1
pod 0 14 0.0
total 53 113 46.9


line stmt bran cond sub pod time code
1             package Aspect::Point::Functions;
2              
3             =pod
4              
5             =head1 NAME
6              
7             Aspect::Point::Functions - Allow point context methods to be called as functions
8              
9             =head1 SYNOPSIS
10              
11             use Aspect::Point::Functions;
12            
13             # This code is equivalent to the SYNOPSIS for Aspect::Point
14             my $advice_code = sub {
15             print type; # The advice type ('before')
16             print pointcut; # The matching pointcut ($pointcut)
17             print enclosing; # Access cflow pointcut advice context
18             print sub_name; # The full package_name::sub_name
19             print package_name; # The package name ('Person')
20             print short_name; # The sub name (a get or set method)
21             print self; # 1st parameter to the matching sub
22             print (args)[1]; # 2nd parameter to the matching sub
23             original->( x => 3 ); # Call matched sub independently
24             return_value(4) # Set the return value
25             };
26              
27             =head1 DESCRIPTION
28              
29             In the AspectJ toolkit for Java which L is inspired by, the join point
30             context information is retrieved through certain keywords.
31              
32             In L this initially proved too difficult to achieve without heavy
33             source code rewriting, and so an alternative approach was taken using a topic
34             object and methods.
35              
36             This B package attempts to implement the original function/keyword
37             style of call.
38              
39             It is considered unsupported at this time.
40              
41             =cut
42              
43 2     2   2037 use strict;
  2         4  
  2         64  
44 2     2   12 use Exporter ();
  2         3  
  2         31  
45 2     2   10 use Aspect::Point ();
  2         5  
  2         1977  
46              
47             our $VERSION = '1.04';
48             our @ISA = 'Exporter';
49             our @EXPORT = qw{
50             type
51             pointcut
52             original
53             sub_name
54             package_name
55             short_name
56             self
57             wantarray
58             args
59             exception
60             return_value
61             enclosing
62             topic
63             proceed
64             };
65              
66             sub type () {
67 0     0 0 0 $_->{type};
68             }
69              
70             sub pointcut () {
71 0     0 0 0 $_->{pointcut};
72             }
73              
74             sub original () {
75 0     0 0 0 $_->{original};
76             }
77              
78             sub sub_name () {
79 0     0 0 0 $_->{sub_name};
80             }
81              
82             sub package_name () {
83 0     0 0 0 my $name = $_->{sub_name};
84 0 0       0 return '' unless $name =~ /::/;
85 0         0 $name =~ s/::[^:]+$//;
86 0         0 return $name;
87             }
88              
89             sub short_name () {
90 0     0 0 0 my $name = $_->{sub_name};
91 0 0       0 return $name unless $name =~ /::/;
92 0         0 $name =~ /::([^:]+)$/;
93 0         0 return $1;
94             }
95              
96             sub self () {
97 0     0 0 0 $_->{args}->[0];
98             }
99              
100             sub wantarray () {
101 5     5 0 61 $_->{wantarray};
102             }
103              
104             sub args {
105 8 100   8 0 125 if ( defined CORE::wantarray ) {
106 4         7 return @{$_->{args}};
  4         28  
107             } else {
108 4         7 @{$_->{args}} = @_;
  4         17  
109             }
110             }
111              
112             sub exception (;$) {
113 0 0   0 0 0 unless ( $_->{type} eq 'after' ) {
114 0         0 Carp::croak("Cannot call exception in $_->{exception} advice");
115             }
116 0 0       0 return $_->{exception} if defined CORE::wantarray();
117 0         0 $_->{exception} = $_[0];
118             }
119              
120             sub return_value (;@) {
121             # Handle usage in getter form
122 7 100   7 0 122 if ( defined CORE::wantarray() ) {
123             # Let the inherent magic of Perl do the work between the
124             # list and scalar context calls to return_value
125 1 0       5 return @{$_->{return_value} || []} if $_->{wantarray};
  0 50       0  
126 1 50       7 return $_->{return_value} if defined $_->{wantarray};
127 0         0 return;
128             }
129              
130             # We've been provided a return value
131 6         23 $_->{exception} = '';
132 6 50       179 $_->{return_value} = $_->{wantarray} ? [ @_ ] : pop;
133             }
134              
135             sub enclosing () {
136 0     0 0 0 $_[0]->{enclosing};
137             }
138              
139             sub topic () {
140 0     0 0 0 Carp::croak("The join point method topic in reserved");
141             }
142              
143             sub proceed () {
144 10     10 0 121 my $self = $_;
145              
146 10 50       33 unless ( $self->{type} eq 'around' ) {
147 0         0 Carp::croak("Cannot call proceed in $self->{type} advice");
148             }
149              
150 10         16 local $_ = ${$self->{topic}};
  10         24  
151              
152 10 100       43 if ( $self->{wantarray} ) {
    100          
153 1         5 $self->return_value(
154             Sub::Uplevel::uplevel(
155             2,
156             $self->{original},
157 1         3 @{$self->{args}},
158             )
159             );
160              
161             } elsif ( defined $self->{wantarray} ) {
162 8         90 $self->return_value(
163             scalar Sub::Uplevel::uplevel(
164             2,
165             $self->{original},
166 8         15 @{$self->{args}},
167             )
168             );
169              
170             } else {
171 1         6 Sub::Uplevel::uplevel(
172             2,
173             $self->{original},
174 1         3 @{$self->{args}},
175             );
176             }
177              
178 10         29 ${$self->{topic}} = $_;
  10         19  
179              
180 10         254 return;
181             }
182              
183             1;
184              
185             =pod
186              
187             =head1 AUTHORS
188              
189             Adam Kennedy Eadamk@cpan.orgE
190              
191             =head1 COPYRIGHT
192              
193             Copyright 2011 Adam Kennedy.
194              
195             This library is free software; you can redistribute it and/or modify
196             it under the same terms as Perl itself.
197              
198             =cut