File Coverage

blib/lib/Class/Decorator.pm
Criterion Covered Total %
statement 73 101 72.2
branch 11 30 36.6
condition 8 12 66.6
subroutine 12 13 92.3
pod 0 4 0.0
total 104 160 65.0


line stmt bran cond sub pod time code
1             package Class::Decorator;
2 1     1   6485 use Carp;
  1         3  
  1         69  
3 1     1   5 use strict;
  1         2  
  1         33  
4 1     1   6 use vars qw ( $VERSION $METH $METHOD $AUTOLOAD );
  1         13  
  1         867  
5              
6             $VERSION = '0.99';
7              
8             sub new
9             {
10 5     5 0 305 my ($caller, %args) = @_;
11 5   33     25 my $class = ref($caller) || $caller;
12             bless {
13 10     10   12 pre => $args{pre} || sub {}, # performed before dispatched method
14 10     10   11 post => $args{post} || sub {}, # performed after dispatched method
15 5   100     85 obj => $args{obj} || croak("decorator must be constructed with a component to be decorated"),
      100        
      33        
      100        
16             methods => $args{methods} || {}
17             }, $class;
18             }
19              
20 0     0   0 sub DESTROY {}
21              
22             sub VERSION
23             {
24 2     2 0 36 my ($self, @args) = @_;
25 2         6 my ($pre, $post) = ($self->{pre}, $self->{post});
26            
27 2 50       2 if (exists ${$self->{methods}}{VERSION}) {
  2         7  
28 0 0       0 if (exists ${$self->{methods}->{VERSION}}{pre}) {
  0         0  
29 0         0 $pre = ${$self->{methods}->{VERSION}}{pre};
  0         0  
30             }
31 0 0       0 if (exists ${$self->{methods}->{VERSION}}{post}) {
  0         0  
32 0         0 $post = ${$self->{methods}->{VERSION}}{post};
  0         0  
33             }
34             }
35            
36 2         4 $pre->(@args);
37 2         41 my $return_value = $self->{obj}->VERSION(@args);
38 2         8 $post->(@args);
39 2         32 return $return_value;
40             }
41              
42             sub isa
43             {
44 4     4 0 74 my ($self, @args) = @_;
45 4         10 my ($pre, $post) = ($self->{pre}, $self->{post});
46            
47 4 50       4 if (exists ${$self->{methods}}{isa}) {
  4         32  
48 0 0       0 if (exists ${$self->{methods}->{isa}}{pre}) {
  0         0  
49 0         0 $pre = ${$self->{methods}->{isa}}{pre};
  0         0  
50             }
51 0 0       0 if (exists ${$self->{methods}->{isa}}{post}) {
  0         0  
52 0         0 $post = ${$self->{methods}->{isa}}{post};
  0         0  
53             }
54             }
55            
56 4         9 $pre->(@args);
57 4         29 my $return_value = $self->{obj}->isa(@args);
58 4         12 $post->(@args);
59 4         19 return $return_value;
60             }
61              
62             sub can
63             {
64 4     4 0 76 my ($self, @args) = @_;
65 4         7 my ($pre, $post) = ($self->{pre}, $self->{post});
66            
67 4 50       3 if (exists ${$self->{methods}}{can}) {
  4         13  
68 0 0       0 if (exists ${$self->{methods}->{can}}{pre}) {
  0         0  
69 0         0 $pre = ${$self->{methods}->{can}}{pre};
  0         0  
70             }
71 0 0       0 if (exists ${$self->{methods}->{can}}{post}) {
  0         0  
72 0         0 $post = ${$self->{methods}->{can}}{post};
  0         0  
73             }
74             }
75            
76 4         33 $pre->(@args);
77 4         28 my $return_value = $self->{obj}->can(@args);
78 4         9 $post->(@args);
79 4         19 return $return_value;
80             }
81              
82             sub AUTOLOAD
83             {
84 1     1   73 my ($self, @args) = @_;
85              
86             # check to see whether method name is of form Foo::Bar::Baz
87 1 50       12 if ($AUTOLOAD =~ /.+::(.+)$/) {
88 1         5 $METHOD = $METH = $1; # $METH for backward compaitibility (v0.01)
89             } else {
90 0         0 die("cannot find method name");
91             }
92              
93 1         19 my $dispatch = $self->{obj}->can($METHOD);
94              
95             ############################
96             # construct the subroutine #
97             ############################
98             my $sub = sub {
99 12     12   314 my ($decorator, @args) = @_;
100 12         27 my ($pre, $post) = ($decorator->{pre}, $decorator->{post});
101 12 100       13 if (exists ${$decorator->{methods}}{$METHOD}) {
  12         31  
102 1 50       1 if (exists ${$decorator->{methods}->{$METHOD}}{pre}) {
  1         5  
103 1         2 $pre = ${$decorator->{methods}->{$METHOD}}{pre};
  1         2  
104             }
105 1 50       2 if (exists ${$decorator->{methods}->{$METHOD}}{post}) {
  1         4  
106 1         2 $post = ${$decorator->{methods}->{$METHOD}}{post};
  1         3  
107             }
108             }
109              
110 12 100       24 if (wantarray) {
111 7         16 () = $pre->(@args);
112 7         44 my @return_values = $decorator->{obj}->$METHOD(@args);
113 7         29 () = $post->(@args);
114 7         47 return @return_values;
115             } else {
116 5         9 $pre->(@args);
117 5         26 my $return_value = $decorator->{obj}->$METHOD(@args);
118 5         26 $post->(@args);
119 5         24 return $return_value;
120             }
121 1         7 };
122            
123             ###########################
124             # load the subroutine #
125             ###########################
126             {
127 1     1   6 no strict "refs"; # keep following line happy
  1         1  
  1         106  
  1         4  
128 1         2 *{$AUTOLOAD} = $sub;
  1         5  
129             }
130            
131             ############################
132             # call the subroutine #
133             ############################
134 1 50       4 if (wantarray) {
135 0         0 my @return_values = $sub->($self, @args);
136 0         0 return @return_values;
137             } else {
138 1         4 my $return_value = $sub->($self, @args);
139 1         13 return $return_value;
140             }
141             }
142              
143             1;
144             __END__