10 while (my $next = shift @inlist) {
13 unshift @inlist, @{"$outlist[-1]::ISA"};
21 my $caller = (caller(1))[3];
22 my $wanted = $NEXT::AUTOLOAD || 'NEXT::AUTOLOAD';
23 undef $NEXT::AUTOLOAD;
24 my ($caller_class, $caller_method) = $caller =~ m{(.*)::(.*)}g;
25 my ($wanted_class, $wanted_method) = $wanted =~ m{(.*)::(.*)}g;
26 croak "Can't call $wanted from $caller"
27 unless $caller_method eq $wanted_method;
29 local ($NEXT::NEXT{$self,$wanted_method}, $NEXT::SEEN) =
30 ($NEXT::NEXT{$self,$wanted_method}, $NEXT::SEEN);
33 unless ($NEXT::NEXT{$self,$wanted_method}) {
35 ancestors ref $self || $self, $wanted_class;
37 last if shift @forebears eq $caller_class
40 @{$NEXT::NEXT{$self,$wanted_method}} =
41 map { *{"${_}::$caller_method"}{CODE}||() } @forebears
42 unless $wanted_method eq 'AUTOLOAD';
43 @{$NEXT::NEXT{$self,$wanted_method}} =
44 map { (*{"${_}::AUTOLOAD"}{CODE}) ? "${_}::AUTOLOAD" : ()} @forebears
45 unless @{$NEXT::NEXT{$self,$wanted_method}||[]};
46 $NEXT::SEEN->{$self,*{$caller}{CODE}}++;
48 my $call_method = shift @{$NEXT::NEXT{$self,$wanted_method}};
49 while ($wanted_class =~ /^NEXT:.*:UNSEEN/ && defined $call_method
50 && $NEXT::SEEN->{$self,$call_method}++) {
51 $call_method = shift @{$NEXT::NEXT{$self,$wanted_method}};
53 unless (defined $call_method) {
54 return unless $wanted_class =~ /^NEXT:.*:ACTUAL/;
55 (local $Carp::CarpLevel)++;
56 croak qq(Can't locate object method "$wanted_method" ),
57 qq(via package "$caller_class");
59 return shift()->$call_method(@_) if ref $call_method eq 'CODE';
61 ($wanted_method=${$caller_class."::AUTOLOAD"}) =~ s/.*:://
62 if $wanted_method eq 'AUTOLOAD';
63 $$call_method = $caller_class."::NEXT::".$wanted_method;
64 return $call_method->(@_);
68 package NEXT::UNSEEN; @ISA = 'NEXT';
69 package NEXT::ACTUAL; @ISA = 'NEXT';
70 package NEXT::ACTUAL::UNSEEN; @ISA = 'NEXT';
71 package NEXT::UNSEEN::ACTUAL; @ISA = 'NEXT';
79 NEXT.pm - Provide a pseudo-class NEXT that allows method redispatch
87 sub A::method { print "$_[0]: A method\n"; $_[0]->NEXT::method() }
88 sub A::DESTROY { print "$_[0]: A dtor\n"; $_[0]->NEXT::DESTROY() }
92 sub B::AUTOLOAD { print "$_[0]: B AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
93 sub B::DESTROY { print "$_[0]: B dtor\n"; $_[0]->NEXT::DESTROY() }
96 sub C::method { print "$_[0]: C method\n"; $_[0]->NEXT::method() }
97 sub C::AUTOLOAD { print "$_[0]: C AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
98 sub C::DESTROY { print "$_[0]: C dtor\n"; $_[0]->NEXT::DESTROY() }
102 sub D::method { print "$_[0]: D method\n"; $_[0]->NEXT::method() }
103 sub D::AUTOLOAD { print "$_[0]: D AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
104 sub D::DESTROY { print "$_[0]: D dtor\n"; $_[0]->NEXT::DESTROY() }
108 my $obj = bless {}, "D";
110 $obj->method(); # Calls D::method, A::method, C::method
111 $obj->missing_method(); # Calls D::AUTOLOAD, B::AUTOLOAD, C::AUTOLOAD
113 # Clean-up calls D::DESTROY, B::DESTROY, A::DESTROY, C::DESTROY
118 NEXT.pm adds a pseudoclass named C<NEXT> to any program
119 that uses it. If a method C<m> calls C<$self->NEXT::m()>, the call to
120 C<m> is redispatched as if the calling method had not originally been found.
122 In other words, a call to C<$self->NEXT::m()> resumes the depth-first,
123 left-to-right search of C<$self>'s class hierarchy that resulted in the
124 original call to C<m>.
126 Note that this is not the same thing as C<$self->SUPER::m()>, which
127 begins a new dispatch that is restricted to searching the ancestors
128 of the current class. C<$self->NEXT::m()> can backtrack
129 past the current class -- to look for a suitable method in other
130 ancestors of C<$self> -- whereas C<$self->SUPER::m()> cannot.
132 A typical use would be in the destructors of a class hierarchy,
133 as illustrated in the synopsis above. Each class in the hierarchy
134 has a DESTROY method that performs some class-specific action
135 and then redispatches the call up the hierarchy. As a result,
136 when an object of class D is destroyed, the destructors of I<all>
137 its parent classes are called (in depth-first, left-to-right order).
139 Another typical use of redispatch would be in C<AUTOLOAD>'ed methods.
140 If such a method determined that it was not able to handle a
141 particular call, it might choose to redispatch that call, in the
142 hope that some other C<AUTOLOAD> (above it, or to its left) might
145 By default, if a redispatch attempt fails to find another method
146 elsewhere in the objects class hierarchy, it quietly gives up and does
147 nothing (but see L<"Enforcing redispatch">). This gracious acquiesence
148 is also unlike the (generally annoying) behaviour of C<SUPER>, which
149 throws an exception if it cannot redispatch.
151 Note that it is a fatal error for any method (including C<AUTOLOAD>)
152 to attempt to redispatch any method that does not have the
153 same name. For example:
155 sub D::oops { print "oops!\n"; $_[0]->NEXT::other_method() }
158 =head2 Enforcing redispatch
160 It is possible to make C<NEXT> redispatch more demandingly (i.e. like
161 C<SUPER> does), so that the redispatch throws an exception if it cannot
162 find a "next" method to call.
164 To do this, simple invoke the redispatch as:
166 $self->NEXT::ACTUAL::method();
170 $self->NEXT::method();
172 The C<ACTUAL> tells C<NEXT> that there must actually be a next method to call,
173 or it should throw an exception.
175 C<NEXT::ACTUAL> is most commonly used in C<AUTOLOAD> methods, as a means to
176 decline an C<AUTOLOAD> request, but preserve the normal exception-on-failure
180 if ($AUTOLOAD =~ /foo|bar/) {
183 else { # try elsewhere
184 shift()->NEXT::ACTUAL::AUTOLOAD(@_);
188 By using C<NEXT::ACTUAL>, if there is no other C<AUTOLOAD> to handle the
189 method call, an exception will be thrown (as usually happens in the absence of
190 a suitable C<AUTOLOAD>).
193 =head2 Avoiding repetitions
195 If C<NEXT> redispatching is used in the methods of a "diamond" class hierarchy:
206 sub foo { print "called A::foo\n"; shift->NEXT::foo() }
209 sub foo { print "called B::foo\n"; shift->NEXT::foo() }
211 package C; @ISA = qw( A );
212 sub foo { print "called C::foo\n"; shift->NEXT::foo() }
214 package D; @ISA = qw(A B);
215 sub foo { print "called D::foo\n"; shift->NEXT::foo() }
217 package E; @ISA = qw(C D);
218 sub foo { print "called E::foo\n"; shift->NEXT::foo() }
222 then derived classes may (re-)inherit base-class methods through two or
223 more distinct paths (e.g. in the way C<E> inherits C<A::foo> twice --
224 through C<C> and C<D>). In such cases, a sequence of C<NEXT> redispatches
225 will invoke the multiply inherited method as many times as it is
226 inherited. For example, the above code prints:
235 (i.e. C<A::foo> is called twice).
237 In some cases this I<may> be the desired effect within a diamond hierarchy,
238 but in others (e.g. for destructors) it may be more appropriate to
239 call each method only once during a sequence of redispatches.
241 To cover such cases, you can redispatch methods via:
243 $self->NEXT::UNSEEN::method();
247 $self->NEXT::method();
249 This causes the redispatcher to skip any classes in the hierarchy that it has
250 already visited in an earlier redispatch. So, for example, if the
251 previous example were rewritten:
254 sub foo { print "called A::foo\n"; shift->NEXT::UNSEEN::foo() }
257 sub foo { print "called B::foo\n"; shift->NEXT::UNSEEN::foo() }
259 package C; @ISA = qw( A );
260 sub foo { print "called C::foo\n"; shift->NEXT::UNSEEN::foo() }
262 package D; @ISA = qw(A B);
263 sub foo { print "called D::foo\n"; shift->NEXT::UNSEEN::foo() }
265 package E; @ISA = qw(C D);
266 sub foo { print "called E::foo\n"; shift->NEXT::UNSEEN::foo() }
278 and omit the second call to C<A::foo>.
280 Note that you can also use:
282 $self->NEXT::UNSEEN::ACTUAL::method();
286 $self->NEXT::ACTUAL::UNSEEN::method();
288 to get both unique invocation I<and> exception-on-failure.
293 Damian Conway (damian@conway.org)
295 =head1 BUGS AND IRRITATIONS
297 Because it's a module, not an integral part of the interpreter, NEXT.pm
298 has to guess where the surrounding call was found in the method
299 look-up sequence. In the presence of diamond inheritance patterns
300 it occasionally guesses wrong.
302 It's also too slow (despite caching).
304 Comment, suggestions, and patches welcome.
308 Copyright (c) 2000-2001, Damian Conway. All Rights Reserved.
309 This module is free software. It may be used, redistributed
310 and/or modified under the same terms as Perl itself.