File Coverage

lib/SUPER.pm
Criterion Covered Total %
statement 72 72 100.0
branch 19 20 95.0
condition 3 5 60.0
subroutine 16 16 100.0
pod 3 6 50.0
total 113 119 94.9


line stmt bran cond sub pod time code
1             # Dear PAUSE: please do not index this
2             package
3             DB;
4              
5 3     3 0 26 sub uplevel_args { my @foo = caller(2); return @DB::args }
  3         12  
6              
7             # Dear PAUSE: nor this
8             package
9             UNIVERSAL;
10              
11 7     7   169004 use strict;
  7         26  
  7         359  
12 7     7   38 use warnings;
  7         13  
  7         237  
13              
14 7     7   41 use Scalar::Util 'blessed';
  7         21  
  7         2859  
15              
16             sub super
17             {
18 7     7 0 22 return ( SUPER::find_parent( @_, '', $_[0] ) )[0];
19             }
20              
21             sub SUPER
22             {
23 14     14 0 8703 my $self = $_[0];
24 14         53 my $blessed = blessed( $self );
25 14 100       45 my $self_class = defined $blessed ? $blessed : $self;
26 14         148 my ($class, $method) = ( caller( 1 ) )[3] =~ /(.+)::(\w+)$/;
27 14         52 my ($sub, $parent) =
28             SUPER::find_parent( $self_class, $method, $class, $self );
29              
30 14 100       43 return unless $sub;
31 13         65 goto &$sub;
32             }
33              
34             package SUPER;
35             {
36             $SUPER::VERSION = '1.20120705';
37             }
38             # ABSTRACT: control superclass method dispatch
39              
40 7     7   42 use strict;
  7         11  
  7         237  
41 7     7   46 use warnings;
  7         11  
  7         232  
42              
43 7     7   113 use base 'Exporter';
  7         10  
  7         1139  
44              
45             @SUPER::ISA = 'Exporter';
46             @SUPER::EXPORT = 'super';
47              
48 7     7   44 use Carp;
  7         12  
  7         625  
49              
50 7     7   43 use Scalar::Util 'blessed';
  7         17  
  7         484  
51 7     7   7517 use Sub::Identify ();
  7         8504  
  7         2297  
52              
53             sub find_parent
54             {
55 25     25 1 4690 my ($class, $method, $prune, $invocant) = @_;
56 25         61 my $blessed = blessed( $class );
57 25   33     103 $invocant ||= $class;
58 25 100       59 $class = $blessed if $blessed;
59 25   100     82 $prune ||= '';
60              
61 25         187 my @parents = get_all_parents( $invocant, $class );
62              
63             # only check parents above the $prune point
64 25         56 my $i = $#parents;
65 25         47 for my $parent (reverse @parents) {
66 61 100       132 last if $parent eq $prune;
67 55         92 $i--;
68             }
69              
70 25         202 for my $parent ( @parents[$i .. $#parents] )
71             {
72 49 100       333 if ( my $subref = $parent->can( $method ) )
73             {
74 30         150 my $source = Sub::Identify::sub_fullname( $subref );
75 30 100       969 next if $source eq "${prune}::$method";
76 23         110 return ( $subref, $parent );
77             }
78             }
79             }
80              
81             sub get_all_parents
82             {
83 75     75 1 3163 my ($invocant, $class) = @_;
84              
85 75         108 my @parents = eval { $invocant->__get_parents() };
  75         697  
86              
87 75 100       224 unless ( @parents )
88             {
89 7     7   171 no strict 'refs';
  7         15  
  7         1900  
90 74         83 @parents = @{ $class . '::ISA' };
  74         328  
91             }
92              
93 75 100       294 return 'UNIVERSAL' unless @parents;
94 46         92 return @parents, map { get_all_parents( $_, $_ ) } @parents;
  46         106  
95             }
96              
97             sub super()
98             {
99             # Someone's trying to find SUPER's super. Blah.
100 6 100   6 1 3996 goto &UNIVERSAL::super if @_;
101              
102 3         10 @_ = DB::uplevel_args();
103              
104 3 50       13 carp 'You must call super() from a method call' unless $_[0];
105              
106 3         13 my $caller = ( caller(1) )[3];
107 3         8 my $self = caller();
108 3         13 $caller =~ s/.*:://;
109              
110 3         4 goto &{ $self->UNIVERSAL::super($caller) };
  3         17  
111             }
112              
113             1;
114              
115             =head1 NAME
116              
117             SUPER - control superclass method dispatch
118              
119             =head1 SYNOPSIS
120              
121             Find the parent method that would run if this weren't here:
122              
123             sub my_method
124             {
125             my $self = shift;
126             my $super = $self->super('my_method'); # Who's your daddy?
127              
128             if ($want_to_deal_with_this)
129             {
130             # ...
131             }
132             else
133             {
134             $super->($self, @_)
135             }
136             }
137              
138             Or Ruby-style:
139              
140             sub my_method
141             {
142             my $self = shift;
143              
144             if ($want_to_deal_with_this)
145             {
146             # ...
147             }
148             else
149             {
150             super;
151             }
152             }
153              
154             Or call the super method manually, with respect to inheritance, and passing
155             different arguments:
156              
157             sub my_method
158             {
159             my $self = shift;
160              
161             # parent handles args backwardly
162             $self->SUPER( reverse @_ );
163             }
164              
165             =head1 DESCRIPTION
166              
167             When subclassing a class, you occasionally want to dispatch control to the
168             superclass -- at least conditionally and temporarily. The Perl syntax for
169             calling your superclass is ugly and unwieldy:
170              
171             $self->SUPER::method(@_);
172              
173             especially when compared to its Ruby equivalent:
174              
175             super;
176              
177             It's even worse in that the normal Perl redispatch mechanism only dispatches to
178             the parent of the class containing the method I. That doesn't work very well for mixins and roles.
179              
180             This module provides nicer equivalents, along with the universal method
181             C to determine a class' own superclass. This allows you to do things
182             such as:
183              
184             goto &{$_[0]->super('my_method')};
185              
186             if you don't like wasting precious stack frames. (Because C returns a
187             coderef, much like L, this doesn't break C.)
188              
189             If you are using roles or mixins or otherwise pulling in methods from other
190             packages that need to dispatch to their super methods, or if you want to pass
191             different arguments to the super method, use the C method:
192              
193             $self->SUPER( qw( other arguments here ) );
194              
195             =head1 FUNCTIONS and METHODS
196              
197             This module provides the following functions and methods:
198              
199             =over
200              
201             =item C
202              
203             This function calls the super method of the currently-executing method, no
204             matter where the super method is in the hierarchy.
205              
206             This takes no arguments; it passes the same arguments passed to the
207             currently-executing method.
208              
209             The module exports this function by default.
210              
211             I: you I have the appropriate C declaration in place for
212             this to work. That is, you must have I the method in which you use
213             this function in the package from which you want to use it. Them's the breaks
214             with Perl 5.
215              
216             =item C
217              
218             Attempts to find a parent implementation of C<$method> starting with C<$class>.
219             If you pass C<$prune>, it will not ignore the method found in that package, if
220             it exists there. Pass C<$invocant> if the object itself might have a different
221             idea of its parents.
222              
223             The module does not export this function by default. Call it directly.
224              
225             =item C
226              
227             Returns all of the parents for the C<$invocant>, if it supports the
228             C<__get_parents()> method or the contents of C<@ISA> for C<$class>. You
229             probably oughtn't call this on your own.
230              
231             =item C
232              
233             Calls the super method of the currently-executing method. You I pass
234             arguments. This is a method.
235              
236             =back
237              
238             =head1 NOTES
239              
240             I if you do weird things with code generation, be sure to I your
241             anonymous subroutines. See I #57.
242              
243             Using C doesn't let you pass alternate arguments to your superclass's
244             method. If you want to pass different arguments, use C instead. D'oh.
245              
246             This module does a small amount of Deep Magic to find the arguments of method
247             I C itself. This may confuse tools such as C.
248              
249             In your own code, if you do complicated things with proxy objects and the like,
250             define C<__get_parents()> to return a list of all parents of the object to
251             which you really want to dispatch.
252              
253             =head1 AUTHOR
254              
255             Created by Simon Cozens, C. Copyright (c) 2003 Simon Cozens.
256              
257             Maintained by chromatic, Echromatic at wgz dot orgE after version 1.01.
258             Copyright (c) 2004-2012 chromatic.
259              
260             Thanks to Joshua ben Jore for bug reports and suggestions.
261              
262             =head1 LICENSE
263              
264             You may use and distribute this silly little module under the same terms as
265             Perl itself.