File Coverage

lib/SUPER.pm
Criterion Covered Total %
statement 77 77 100.0
branch 19 20 95.0
condition 3 5 60.0
subroutine 17 17 100.0
pod 3 6 50.0
total 119 125 95.2


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 27 sub uplevel_args { my @foo = caller(2); return @DB::args }
  3         11  
6              
7             # Dear PAUSE: nor this
8             package
9             UNIVERSAL;
10              
11 7     7   78032 use strict;
  7         14  
  7         248  
12 7     7   32 use warnings;
  7         11  
  7         277  
13              
14 7     7   31 use Scalar::Util 'blessed';
  7         16  
  7         2078  
15              
16             sub super
17             {
18 5     5 0 14 return ( SUPER::find_parent( @_, '', $_[0] ) )[0];
19             }
20              
21             sub SUPER
22             {
23 14     14 0 9467 my $self = $_[0];
24 14         69 my $blessed = blessed( $self );
25 14 100       48 my $self_class = defined $blessed ? $blessed : $self;
26 14         177 my ($class, $method) = ( caller( 1 ) )[3] =~ /(.+)::(\w+)$/;
27 14         45 my ($sub, $parent) =
28             SUPER::find_parent( $self_class, $method, $class, $self );
29              
30 14 100       38 return unless $sub;
31 13         62 goto &$sub;
32             }
33              
34             package SUPER;
35             # ABSTRACT: control superclass method dispatch
36             $SUPER::VERSION = '1.20141117';
37 7     7   36 use strict;
  7         11  
  7         182  
38 7     7   29 use warnings;
  7         9  
  7         235  
39              
40 7     7   33 use Carp;
  7         9  
  7         504  
41              
42 7     7   34 use Scalar::Util 'blessed';
  7         8  
  7         362  
43 7     7   4180 use Sub::Identify ();
  7         7554  
  7         352  
44              
45             # no need to use Exporter
46             sub import
47             {
48 10     10   24501 my ($class) = @_;
49 10         25 my $caller = caller();
50 7     7   43 do { no strict 'refs'; *{ $caller . '::super' } = \&super };
  7         10  
  7         1911  
  10         12  
  10         18  
  10         1628  
51             }
52              
53             sub find_parent
54             {
55 23     23 1 3033 my ($class, $method, $prune, $invocant) = @_;
56 23         66 my $blessed = blessed( $class );
57 23   33     85 $invocant ||= $class;
58 23 100       49 $class = $blessed if $blessed;
59 23   100     64 $prune ||= '';
60              
61 23         46 my @parents = get_all_parents( $invocant, $class );
62              
63             # only check parents above the $prune point
64 23         37 my $i = $#parents;
65 23         40 for my $parent (reverse @parents) {
66 57 100       169 last if $parent eq $prune;
67 51         58 $i--;
68             }
69              
70 23         68 for my $parent ( @parents[$i .. $#parents] )
71             {
72 45 100       242 if ( my $subref = $parent->can( $method ) )
73             {
74 28         75 my $source = Sub::Identify::sub_fullname( $subref );
75 28 100       199 next if $source eq "${prune}::$method";
76 21         96 return ( $subref, $parent );
77             }
78             }
79             }
80              
81             sub get_all_parents
82             {
83 71     71 1 2177 my ($invocant, $class) = @_;
84              
85 71         71 my @parents = eval { $invocant->__get_parents() };
  71         562  
86              
87 71 100       200 unless ( @parents )
88             {
89 7     7   97 no strict 'refs';
  7         11  
  7         1585  
90 70         60 @parents = @{ $class . '::ISA' };
  70         230  
91             }
92              
93 71 100       214 return 'UNIVERSAL' unless @parents;
94 44         55 return @parents, map { get_all_parents( $_, $_ ) } @parents;
  44         84  
95             }
96              
97             sub super()
98             {
99             # Someone's trying to find SUPER's super. Blah.
100 5 100   5 1 2897 goto &UNIVERSAL::super if @_;
101              
102 3         6 @_ = DB::uplevel_args();
103              
104 3 50       9 carp 'You must call super() from a method call' unless $_[0];
105              
106 3         11 my $caller = ( caller(1) )[3];
107 3         5 my $self = caller();
108 3         13 $caller =~ s/.*:://;
109              
110 3         4 goto &{ $self->UNIVERSAL::super($caller) };
  3         8  
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.
187              
188             If you are using roles or mixins or otherwise pulling in methods from other
189             packages that need to dispatch to their super methods, or if you want to pass
190             different arguments to the super method, use the C method:
191              
192             $self->SUPER( qw( other arguments here ) );
193              
194             =head1 FUNCTIONS and METHODS
195              
196             This module provides the following functions and methods:
197              
198             =over
199              
200             =item C
201              
202             This function calls the super method of the currently-executing method, no
203             matter where the super method is in the hierarchy.
204              
205             This takes no arguments; it passes the same arguments passed to the
206             currently-executing method.
207              
208             The module exports this function by default.
209              
210             I: you I have the appropriate C declaration in place for
211             this to work. That is, you must have I the method in which you use
212             this function in the package from which you want to use it. Them's the breaks
213             with Perl 5.
214              
215             =item C
216              
217             Attempts to find a parent implementation of C<$method> starting with C<$class>.
218             If you pass C<$prune>, it will not ignore the method found in that package, if
219             it exists there. Pass C<$invocant> if the object itself might have a different
220             idea of its parents.
221              
222             The module does not export this function by default. Call it directly.
223              
224             =item C
225              
226             Returns all of the parents for the C<$invocant>, if it supports the
227             C<__get_parents()> method or the contents of C<@ISA> for C<$class>. You
228             probably oughtn't call this on your own.
229              
230             =item C
231              
232             Calls the super method of the currently-executing method. You I pass
233             arguments. This is a method.
234              
235             =back
236              
237             =head1 NOTES
238              
239             I if you do weird things with code generation, be sure to I your
240             anonymous subroutines. See I #57.
241              
242             Using C doesn't let you pass alternate arguments to your superclass's
243             method. If you want to pass different arguments, use C instead. D'oh.
244              
245             This module does a small amount of Deep Magic to find the arguments of method
246             I C itself. This may confuse tools such as C.
247              
248             In your own code, if you do complicated things with proxy objects and the like,
249             define C<__get_parents()> to return a list of all parents of the object to
250             which you really want to dispatch.
251              
252             =head1 AUTHOR
253              
254             Created by Simon Cozens, C. Copyright (c) 2003 Simon Cozens.
255              
256             Maintained by chromatic, Echromatic at wgz dot orgE after version 1.01.
257             Copyright (c) 2004-2014 chromatic.
258              
259             Thanks to Joshua ben Jore for bug reports and suggestions.
260              
261             =head1 LICENSE
262              
263             You may use and distribute this silly little module under the same terms as
264             Perl itself.