1NEXT(3pm) Perl Programmers Reference Guide NEXT(3pm)
2
3
4
6 NEXT.pm - Provide a pseudo-class NEXT (et al) that allows method
7 redispatch
8
10 use NEXT;
11
12 package A;
13 sub A::method { print "$_[0]: A method\n"; $_[0]->NEXT::method() }
14 sub A::DESTROY { print "$_[0]: A dtor\n"; $_[0]->NEXT::DESTROY() }
15
16 package B;
17 use base qw( A );
18 sub B::AUTOLOAD { print "$_[0]: B AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
19 sub B::DESTROY { print "$_[0]: B dtor\n"; $_[0]->NEXT::DESTROY() }
20
21 package C;
22 sub C::method { print "$_[0]: C method\n"; $_[0]->NEXT::method() }
23 sub C::AUTOLOAD { print "$_[0]: C AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
24 sub C::DESTROY { print "$_[0]: C dtor\n"; $_[0]->NEXT::DESTROY() }
25
26 package D;
27 use base qw( B C );
28 sub D::method { print "$_[0]: D method\n"; $_[0]->NEXT::method() }
29 sub D::AUTOLOAD { print "$_[0]: D AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
30 sub D::DESTROY { print "$_[0]: D dtor\n"; $_[0]->NEXT::DESTROY() }
31
32 package main;
33
34 my $obj = bless {}, "D";
35
36 $obj->method(); # Calls D::method, A::method, C::method
37 $obj->missing_method(); # Calls D::AUTOLOAD, B::AUTOLOAD, C::AUTOLOAD
38
39 # Clean-up calls D::DESTROY, B::DESTROY, A::DESTROY, C::DESTROY
40
42 NEXT.pm adds a pseudoclass named "NEXT" to any program that uses it. If
43 a method "m" calls "$self->NEXT::m()", the call to "m" is redispatched
44 as if the calling method had not originally been found.
45
46 In other words, a call to "$self->NEXT::m()" resumes the depth-first,
47 left-to-right search of $self's class hierarchy that resulted in the
48 original call to "m".
49
50 Note that this is not the same thing as "$self->SUPER::m()", which
51 begins a new dispatch that is restricted to searching the ancestors of
52 the current class. "$self->NEXT::m()" can backtrack past the current
53 class -- to look for a suitable method in other ancestors of $self --
54 whereas "$self->SUPER::m()" cannot.
55
56 A typical use would be in the destructors of a class hierarchy, as
57 illustrated in the synopsis above. Each class in the hierarchy has a
58 DESTROY method that performs some class-specific action and then
59 redispatches the call up the hierarchy. As a result, when an object of
60 class D is destroyed, the destructors of all its parent classes are
61 called (in depth-first, left-to-right order).
62
63 Another typical use of redispatch would be in "AUTOLOAD"'ed methods.
64 If such a method determined that it was not able to handle a particular
65 call, it might choose to redispatch that call, in the hope that some
66 other "AUTOLOAD" (above it, or to its left) might do better.
67
68 By default, if a redispatch attempt fails to find another method
69 elsewhere in the objects class hierarchy, it quietly gives up and does
70 nothing (but see "Enforcing redispatch"). This gracious acquiescence is
71 also unlike the (generally annoying) behaviour of "SUPER", which throws
72 an exception if it cannot redispatch.
73
74 Note that it is a fatal error for any method (including "AUTOLOAD") to
75 attempt to redispatch any method that does not have the same name. For
76 example:
77
78 sub D::oops { print "oops!\n"; $_[0]->NEXT::other_method() }
79
80 Enforcing redispatch
81 It is possible to make "NEXT" redispatch more demandingly (i.e. like
82 "SUPER" does), so that the redispatch throws an exception if it cannot
83 find a "next" method to call.
84
85 To do this, simple invoke the redispatch as:
86
87 $self->NEXT::ACTUAL::method();
88
89 rather than:
90
91 $self->NEXT::method();
92
93 The "ACTUAL" tells "NEXT" that there must actually be a next method to
94 call, or it should throw an exception.
95
96 "NEXT::ACTUAL" is most commonly used in "AUTOLOAD" methods, as a means
97 to decline an "AUTOLOAD" request, but preserve the normal exception-on-
98 failure semantics:
99
100 sub AUTOLOAD {
101 if ($AUTOLOAD =~ /foo|bar/) {
102 # handle here
103 }
104 else { # try elsewhere
105 shift()->NEXT::ACTUAL::AUTOLOAD(@_);
106 }
107 }
108
109 By using "NEXT::ACTUAL", if there is no other "AUTOLOAD" to handle the
110 method call, an exception will be thrown (as usually happens in the
111 absence of a suitable "AUTOLOAD").
112
113 Avoiding repetitions
114 If "NEXT" redispatching is used in the methods of a "diamond" class
115 hierarchy:
116
117 # A B
118 # / \ /
119 # C D
120 # \ /
121 # E
122
123 use NEXT;
124
125 package A;
126 sub foo { print "called A::foo\n"; shift->NEXT::foo() }
127
128 package B;
129 sub foo { print "called B::foo\n"; shift->NEXT::foo() }
130
131 package C; @ISA = qw( A );
132 sub foo { print "called C::foo\n"; shift->NEXT::foo() }
133
134 package D; @ISA = qw(A B);
135 sub foo { print "called D::foo\n"; shift->NEXT::foo() }
136
137 package E; @ISA = qw(C D);
138 sub foo { print "called E::foo\n"; shift->NEXT::foo() }
139
140 E->foo();
141
142 then derived classes may (re-)inherit base-class methods through two or
143 more distinct paths (e.g. in the way "E" inherits "A::foo" twice --
144 through "C" and "D"). In such cases, a sequence of "NEXT" redispatches
145 will invoke the multiply inherited method as many times as it is
146 inherited. For example, the above code prints:
147
148 called E::foo
149 called C::foo
150 called A::foo
151 called D::foo
152 called A::foo
153 called B::foo
154
155 (i.e. "A::foo" is called twice).
156
157 In some cases this may be the desired effect within a diamond
158 hierarchy, but in others (e.g. for destructors) it may be more
159 appropriate to call each method only once during a sequence of
160 redispatches.
161
162 To cover such cases, you can redispatch methods via:
163
164 $self->NEXT::DISTINCT::method();
165
166 rather than:
167
168 $self->NEXT::method();
169
170 This causes the redispatcher to only visit each distinct "method"
171 method once. That is, to skip any classes in the hierarchy that it has
172 already visited during redispatch. So, for example, if the previous
173 example were rewritten:
174
175 package A;
176 sub foo { print "called A::foo\n"; shift->NEXT::DISTINCT::foo() }
177
178 package B;
179 sub foo { print "called B::foo\n"; shift->NEXT::DISTINCT::foo() }
180
181 package C; @ISA = qw( A );
182 sub foo { print "called C::foo\n"; shift->NEXT::DISTINCT::foo() }
183
184 package D; @ISA = qw(A B);
185 sub foo { print "called D::foo\n"; shift->NEXT::DISTINCT::foo() }
186
187 package E; @ISA = qw(C D);
188 sub foo { print "called E::foo\n"; shift->NEXT::DISTINCT::foo() }
189
190 E->foo();
191
192 then it would print:
193
194 called E::foo
195 called C::foo
196 called A::foo
197 called D::foo
198 called B::foo
199
200 and omit the second call to "A::foo" (since it would not be distinct
201 from the first call to "A::foo").
202
203 Note that you can also use:
204
205 $self->NEXT::DISTINCT::ACTUAL::method();
206
207 or:
208
209 $self->NEXT::ACTUAL::DISTINCT::method();
210
211 to get both unique invocation and exception-on-failure.
212
213 Note that, for historical compatibility, you can also use
214 "NEXT::UNSEEN" instead of "NEXT::DISTINCT".
215
216 Invoking all versions of a method with a single call
217 Yet another pseudo-class that NEXT.pm provides is "EVERY". Its
218 behaviour is considerably simpler than that of the "NEXT" family. A
219 call to:
220
221 $obj->EVERY::foo();
222
223 calls every method named "foo" that the object in $obj has inherited.
224 That is:
225
226 use NEXT;
227
228 package A; @ISA = qw(B D X);
229 sub foo { print "A::foo " }
230
231 package B; @ISA = qw(D X);
232 sub foo { print "B::foo " }
233
234 package X; @ISA = qw(D);
235 sub foo { print "X::foo " }
236
237 package D;
238 sub foo { print "D::foo " }
239
240 package main;
241
242 my $obj = bless {}, 'A';
243 $obj->EVERY::foo(); # prints" A::foo B::foo X::foo D::foo
244
245 Prefixing a method call with "EVERY::" causes every method in the
246 object's hierarchy with that name to be invoked. As the above example
247 illustrates, they are not called in Perl's usual "left-most-depth-
248 first" order. Instead, they are called "breadth-first-dependency-wise".
249
250 That means that the inheritance tree of the object is traversed
251 breadth-first and the resulting order of classes is used as the
252 sequence in which methods are called. However, that sequence is
253 modified by imposing a rule that the appropriate method of a derived
254 class must be called before the same method of any ancestral class.
255 That's why, in the above example, "X::foo" is called before "D::foo",
256 even though "D" comes before "X" in @B::ISA.
257
258 In general, there's no need to worry about the order of calls. They
259 will be left-to-right, breadth-first, most-derived-first. This works
260 perfectly for most inherited methods (including destructors), but is
261 inappropriate for some kinds of methods (such as constructors, cloners,
262 debuggers, and initializers) where it's more appropriate that the
263 least-derived methods be called first (as more-derived methods may rely
264 on the behaviour of their "ancestors"). In that case, instead of using
265 the "EVERY" pseudo-class:
266
267 $obj->EVERY::foo(); # prints" A::foo B::foo X::foo D::foo
268
269 you can use the "EVERY::LAST" pseudo-class:
270
271 $obj->EVERY::LAST::foo(); # prints" D::foo X::foo B::foo A::foo
272
273 which reverses the order of method call.
274
275 Whichever version is used, the actual methods are called in the same
276 context (list, scalar, or void) as the original call via "EVERY", and
277 return:
278
279 · A hash of array references in list context. Each entry of the hash
280 has the fully qualified method name as its key and a reference to
281 an array containing the method's list-context return values as its
282 value.
283
284 · A reference to a hash of scalar values in scalar context. Each
285 entry of the hash has the fully qualified method name as its key
286 and the method's scalar-context return values as its value.
287
288 · Nothing in void context (obviously).
289
290 Using "EVERY" methods
291 The typical way to use an "EVERY" call is to wrap it in another base
292 method, that all classes inherit. For example, to ensure that every
293 destructor an object inherits is actually called (as opposed to just
294 the left-most-depth-first-est one):
295
296 package Base;
297 sub DESTROY { $_[0]->EVERY::Destroy }
298
299 package Derived1;
300 use base 'Base';
301 sub Destroy {...}
302
303 package Derived2;
304 use base 'Base', 'Derived1';
305 sub Destroy {...}
306
307 et cetera. Every derived class than needs its own clean-up behaviour
308 simply adds its own "Destroy" method (not a "DESTROY" method), which
309 the call to "EVERY::LAST::Destroy" in the inherited destructor then
310 correctly picks up.
311
312 Likewise, to create a class hierarchy in which every initializer
313 inherited by a new object is invoked:
314
315 package Base;
316 sub new {
317 my ($class, %args) = @_;
318 my $obj = bless {}, $class;
319 $obj->EVERY::LAST::Init(\%args);
320 }
321
322 package Derived1;
323 use base 'Base';
324 sub Init {
325 my ($argsref) = @_;
326 ...
327 }
328
329 package Derived2;
330 use base 'Base', 'Derived1';
331 sub Init {
332 my ($argsref) = @_;
333 ...
334 }
335
336 et cetera. Every derived class than needs some additional
337 initialization behaviour simply adds its own "Init" method (not a "new"
338 method), which the call to "EVERY::LAST::Init" in the inherited
339 constructor then correctly picks up.
340
342 Damian Conway (damian@conway.org)
343
345 Because it's a module, not an integral part of the interpreter, NEXT.pm
346 has to guess where the surrounding call was found in the method look-up
347 sequence. In the presence of diamond inheritance patterns it
348 occasionally guesses wrong.
349
350 It's also too slow (despite caching).
351
352 Comment, suggestions, and patches welcome.
353
355 Copyright (c) 2000-2001, Damian Conway. All Rights Reserved.
356 This module is free software. It may be used, redistributed
357 and/or modified under the same terms as Perl itself.
358
359
360
361perl v5.16.3 2013-03-04 NEXT(3pm)