File Coverage

blib/lib/SUPER.pm
Criterion Covered Total %
statement 81 83 97.5
branch 20 22 90.9
condition 3 5 60.0
subroutine 19 19 100.0
pod 3 6 50.0
total 126 135 93.3


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