2 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns=
"http://www.w3.org/1999/xhtml">
5 <title>NEXT.pm - Provide a pseudo-class NEXT that allows method redispatch
</title>
6 <meta http-equiv=
"content-type" content=
"text/html; charset=utf-8" />
7 <link rev=
"made" href=
"mailto:" />
10 <body style=
"background-color: white">
11 <table border=
"0" width=
"100%" cellspacing=
"0" cellpadding=
"3">
12 <tr><td class=
"block" style=
"background-color: #cccccc" valign=
"middle">
13 <big><strong><span class=
"block"> NEXT.pm - Provide a pseudo-class NEXT that allows method redispatch
</span></strong></big>
17 <p><a name=
"__index__"></a></p>
22 <li><a href=
"#name">NAME
</a></li>
23 <li><a href=
"#synopsis">SYNOPSIS
</a></li>
24 <li><a href=
"#description">DESCRIPTION
</a></li>
27 <li><a href=
"#enforcing_redispatch">Enforcing redispatch
</a></li>
28 <li><a href=
"#avoiding_repetitions">Avoiding repetitions
</a></li>
29 <li><a href=
"#invoking_all_versions_of_a_method_with_a_single_call">Invoking all versions of a method with a single call
</a></li>
30 <li><a href=
"#using_every_methods">Using
<code>EVERY
</code> methods
</a></li>
33 <li><a href=
"#author">AUTHOR
</a></li>
34 <li><a href=
"#bugs_and_irritations">BUGS AND IRRITATIONS
</a></li>
35 <li><a href=
"#copyright">COPYRIGHT
</a></li>
42 <h1><a name=
"name">NAME
</a></h1>
43 <p>NEXT.pm - Provide a pseudo-class NEXT (et al) that allows method redispatch
</p>
47 <h1><a name=
"synopsis">SYNOPSIS
</a></h1>
52 sub A::method { print
"$_[
0]: A method\n
"; $_[
0]-
>NEXT::method() }
53 sub A::DESTROY { print
"$_[
0]: A dtor\n
"; $_[
0]-
>NEXT::DESTROY() }
</pre>
57 sub B::AUTOLOAD { print
"$_[
0]: B AUTOLOAD\n
"; $_[
0]-
>NEXT::AUTOLOAD() }
58 sub B::DESTROY { print
"$_[
0]: B dtor\n
"; $_[
0]-
>NEXT::DESTROY() }
</pre>
61 sub C::method { print
"$_[
0]: C method\n
"; $_[
0]-
>NEXT::method() }
62 sub C::AUTOLOAD { print
"$_[
0]: C AUTOLOAD\n
"; $_[
0]-
>NEXT::AUTOLOAD() }
63 sub C::DESTROY { print
"$_[
0]: C dtor\n
"; $_[
0]-
>NEXT::DESTROY() }
</pre>
67 sub D::method { print
"$_[
0]: D method\n
"; $_[
0]-
>NEXT::method() }
68 sub D::AUTOLOAD { print
"$_[
0]: D AUTOLOAD\n
"; $_[
0]-
>NEXT::AUTOLOAD() }
69 sub D::DESTROY { print
"$_[
0]: D dtor\n
"; $_[
0]-
>NEXT::DESTROY() }
</pre>
73 my $obj = bless {},
"D
";
</pre>
75 $obj-
>method(); # Calls D::method, A::method, C::method
76 $obj-
>missing_method(); # Calls D::AUTOLOAD, B::AUTOLOAD, C::AUTOLOAD
</pre>
78 # Clean-up calls D::DESTROY, B::DESTROY, A::DESTROY, C::DESTROY
</pre>
82 <h1><a name=
"description">DESCRIPTION
</a></h1>
83 <p>NEXT.pm adds a pseudoclass named
<code>NEXT
</code> to any program
84 that uses it. If a method
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_m"><code>m
</code></a> calls
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_m"><code>$self-
>NEXT::m()
</code></a>, the call to
85 <a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_m"><code>m
</code></a> is redispatched as if the calling method had not originally been found.
</p>
86 <p>In other words, a call to
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_m"><code>$self-
>NEXT::m()
</code></a> resumes the depth-first,
87 left-to-right search of
<code>$self
</code>'s class hierarchy that resulted in the
88 original call to
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_m"><code>m
</code></a>.
</p>
89 <p>Note that this is not the same thing as
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_m"><code>$self-
>SUPER::m()
</code></a>, which
90 begins a new dispatch that is restricted to searching the ancestors
91 of the current class.
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_m"><code>$self-
>NEXT::m()
</code></a> can backtrack
92 past the current class -- to look for a suitable method in other
93 ancestors of
<code>$self
</code> -- whereas
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_m"><code>$self-
>SUPER::m()
</code></a> cannot.
</p>
94 <p>A typical use would be in the destructors of a class hierarchy,
95 as illustrated in the synopsis above. Each class in the hierarchy
96 has a DESTROY method that performs some class-specific action
97 and then redispatches the call up the hierarchy. As a result,
98 when an object of class D is destroyed, the destructors of
<em>all
</em>
99 its parent classes are called (in depth-first, left-to-right order).
</p>
100 <p>Another typical use of redispatch would be in
<code>AUTOLOAD
</code>'ed methods.
101 If such a method determined that it was not able to handle a
102 particular call, it might choose to redispatch that call, in the
103 hope that some other
<code>AUTOLOAD
</code> (above it, or to its left) might
105 <p>By default, if a redispatch attempt fails to find another method
106 elsewhere in the objects class hierarchy, it quietly gives up and does
107 nothing (but see
<a href=
"#enforcing_redispatch">Enforcing redispatch
</a>). This gracious acquiesence
108 is also unlike the (generally annoying) behaviour of
<code>SUPER
</code>, which
109 throws an exception if it cannot redispatch.
</p>
110 <p>Note that it is a fatal error for any method (including
<code>AUTOLOAD
</code>)
111 to attempt to redispatch any method that does not have the
112 same name. For example:
</p>
114 sub D::oops { print
"oops!\n
"; $_[
0]-
>NEXT::other_method() }
</pre>
117 <h2><a name=
"enforcing_redispatch">Enforcing redispatch
</a></h2>
118 <p>It is possible to make
<code>NEXT
</code> redispatch more demandingly (i.e. like
119 <code>SUPER
</code> does), so that the redispatch throws an exception if it cannot
120 find a ``next'' method to call.
</p>
121 <p>To do this, simple invoke the redispatch as:
</p>
123 $self-
>NEXT::ACTUAL::method();
</pre>
126 $self-
>NEXT::method();
</pre>
127 <p>The
<code>ACTUAL
</code> tells
<code>NEXT
</code> that there must actually be a next method to call,
128 or it should throw an exception.
</p>
129 <p><code>NEXT::ACTUAL
</code> is most commonly used in
<code>AUTOLOAD
</code> methods, as a means to
130 decline an
<code>AUTOLOAD
</code> request, but preserve the normal exception-on-failure
134 if ($AUTOLOAD =~ /foo|bar/) {
137 else { # try elsewhere
138 shift()-
>NEXT::ACTUAL::AUTOLOAD(@_);
141 <p>By using
<code>NEXT::ACTUAL
</code>, if there is no other
<code>AUTOLOAD
</code> to handle the
142 method call, an exception will be thrown (as usually happens in the absence of
143 a suitable
<code>AUTOLOAD
</code>).
</p>
146 <h2><a name=
"avoiding_repetitions">Avoiding repetitions
</a></h2>
147 <p>If
<code>NEXT
</code> redispatching is used in the methods of a ``diamond'' class hierarchy:
</p>
158 sub foo { print
"called A::foo\n
"; shift-
>NEXT::foo() }
</pre>
161 sub foo { print
"called B::foo\n
"; shift-
>NEXT::foo() }
</pre>
163 package C; @ISA = qw( A );
164 sub foo { print
"called C::foo\n
"; shift-
>NEXT::foo() }
</pre>
166 package D; @ISA = qw(A B);
167 sub foo { print
"called D::foo\n
"; shift-
>NEXT::foo() }
</pre>
169 package E; @ISA = qw(C D);
170 sub foo { print
"called E::foo\n
"; shift-
>NEXT::foo() }
</pre>
173 <p>then derived classes may (re-)inherit base-class methods through two or
174 more distinct paths (e.g. in the way
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_e"><code>E
</code></a> inherits
<code>A::foo
</code> twice --
175 through
<code>C
</code> and
<code>D
</code>). In such cases, a sequence of
<code>NEXT
</code> redispatches
176 will invoke the multiply inherited method as many times as it is
177 inherited. For example, the above code prints:
</p>
185 <p>(i.e.
<code>A::foo
</code> is called twice).
</p>
186 <p>In some cases this
<em>may
</em> be the desired effect within a diamond hierarchy,
187 but in others (e.g. for destructors) it may be more appropriate to
188 call each method only once during a sequence of redispatches.
</p>
189 <p>To cover such cases, you can redispatch methods via:
</p>
191 $self-
>NEXT::DISTINCT::method();
</pre>
194 $self-
>NEXT::method();
</pre>
195 <p>This causes the redispatcher to only visit each distinct
<code>method
</code> method
196 once. That is, to skip any classes in the hierarchy that it has
197 already visited during redispatch. So, for example, if the
198 previous example were rewritten:
</p>
201 sub foo { print
"called A::foo\n
"; shift-
>NEXT::DISTINCT::foo() }
</pre>
204 sub foo { print
"called B::foo\n
"; shift-
>NEXT::DISTINCT::foo() }
</pre>
206 package C; @ISA = qw( A );
207 sub foo { print
"called C::foo\n
"; shift-
>NEXT::DISTINCT::foo() }
</pre>
209 package D; @ISA = qw(A B);
210 sub foo { print
"called D::foo\n
"; shift-
>NEXT::DISTINCT::foo() }
</pre>
212 package E; @ISA = qw(C D);
213 sub foo { print
"called E::foo\n
"; shift-
>NEXT::DISTINCT::foo() }
</pre>
216 <p>then it would print:
225 <p>and omit the second call to
<code>A::foo
</code> (since it would not be distinct
226 from the first call to
<code>A::foo
</code>).
</p>
227 <p>Note that you can also use:
</p>
229 $self-
>NEXT::DISTINCT::ACTUAL::method();
</pre>
232 $self-
>NEXT::ACTUAL::DISTINCT::method();
</pre>
233 <p>to get both unique invocation
<em>and
</em> exception-on-failure.
</p>
234 <p>Note that, for historical compatibility, you can also use
235 <code>NEXT::UNSEEN
</code> instead of
<code>NEXT::DISTINCT
</code>.
</p>
238 <h2><a name=
"invoking_all_versions_of_a_method_with_a_single_call">Invoking all versions of a method with a single call
</a></h2>
239 <p>Yet another pseudo-class that NEXT.pm provides is
<code>EVERY
</code>.
240 Its behaviour is considerably simpler than that of the
<code>NEXT
</code> family.
243 $obj-
>EVERY::foo();
</pre>
244 <p>calls
<em>every
</em> method named
<code>foo
</code> that the object in
<code>$obj
</code> has inherited.
249 package A; @ISA = qw(B D X);
250 sub foo { print
"A::foo
" }
</pre>
252 package B; @ISA = qw(D X);
253 sub foo { print
"B::foo
" }
</pre>
255 package X; @ISA = qw(D);
256 sub foo { print
"X::foo
" }
</pre>
259 sub foo { print
"D::foo
" }
</pre>
263 my $obj = bless {}, 'A';
264 $obj-
>EVERY::foo(); # prints
" A::foo B::foo X::foo D::foo
</pre>
265 <p>Prefixing a method call with
<code>EVERY::
</code> causes every method in the
266 object's hierarchy with that name to be invoked. As the above example
267 illustrates, they are not called in Perl's usual ``left-most-depth-first''
268 order. Instead, they are called ``breadth-first-dependency-wise''.
</p>
269 <p>That means that the inheritance tree of the object is traversed breadth-first
270 and the resulting order of classes is used as the sequence in which methods
271 are called. However, that sequence is modified by imposing a rule that the
272 appropritae method of a derived class must be called before the same method of
273 any ancestral class. That's why, in the above example,
<code>X::foo
</code> is called
274 before
<code>D::foo
</code>, even though
<code>D
</code> comes before
<a href=
"file://C|\msysgit\mingw\html/pod/perlguts.html#item_x"><code>X
</code></a> in
<code>@B::ISA
</code>.
</p>
275 <p>In general, there's no need to worry about the order of calls. They will be
276 left-to-right, breadth-first, most-derived-first. This works perfectly for
277 most inherited methods (including destructors), but is inappropriate for
278 some kinds of methods (such as constructors, cloners, debuggers, and
279 initializers) where it's more appropriate that the least-derived methods be
280 called first (as more-derived methods may rely on the behaviour of their
281 ``ancestors''). In that case, instead of using the
<code>EVERY
</code> pseudo-class:
</p>
283 $obj-
>EVERY::foo(); # prints
" A::foo B::foo X::foo D::foo
</pre>
284 <p>you can use the
<code>EVERY::LAST
</code> pseudo-class:
</p>
286 $obj-
>EVERY::LAST::foo(); # prints
" D::foo X::foo B::foo A::foo
</pre>
287 <p>which reverses the order of method call.
</p>
288 <p>Whichever version is used, the actual methods are called in the same
289 context (list, scalar, or void) as the original call via
<code>EVERY
</code>, and return:
</p>
292 <p>A hash of array references in list context. Each entry of the hash has the
293 fully qualified method name as its key and a reference to an array containing
294 the method's list-context return values as its value.
</p>
297 <p>A reference to a hash of scalar values in scalar context. Each entry of the hash has the
298 fully qualified method name as its key and the method's scalar-context return values as its value.
</p>
301 <p>Nothing in void context (obviously).
</p>
306 <h2><a name=
"using_every_methods">Using
<code>EVERY
</code> methods
</a></h2>
307 <p>The typical way to use an
<code>EVERY
</code> call is to wrap it in another base
308 method, that all classes inherit. For example, to ensure that every
309 destructor an object inherits is actually called (as opposed to just the
310 left-most-depth-first-est one):
</p>
313 sub DESTROY { $_[
0]-
>EVERY::Destroy }
</pre>
317 sub Destroy {...}
</pre>
320 use base 'Base', 'Derived1';
321 sub Destroy {...}
</pre>
322 <p>et cetera. Every derived class than needs its own clean-up
323 behaviour simply adds its own
<code>Destroy
</code> method (
<em>not
</em> a
<code>DESTROY
</code> method),
324 which the call to
<code>EVERY::LAST::Destroy
</code> in the inherited destructor
325 then correctly picks up.
</p>
326 <p>Likewise, to create a class hierarchy in which every initializer inherited by
327 a new object is invoked:
</p>
331 my ($class, %args) = @_;
332 my $obj = bless {}, $class;
333 $obj-
>EVERY::LAST::Init(\%args);
344 use base 'Base', 'Derived1';
349 <p>et cetera. Every derived class than needs some additional initialization
350 behaviour simply adds its own
<code>Init
</code> method (
<em>not
</em> a
<code>new
</code> method),
351 which the call to
<code>EVERY::LAST::Init
</code> in the inherited constructor
352 then correctly picks up.
</p>
356 <h1><a name=
"author">AUTHOR
</a></h1>
357 <p>Damian Conway (
<a href=
"mailto:damian@conway.org">damian@conway.org
</a>)
</p>
361 <h1><a name=
"bugs_and_irritations">BUGS AND IRRITATIONS
</a></h1>
362 <p>Because it's a module, not an integral part of the interpreter, NEXT.pm
363 has to guess where the surrounding call was found in the method
364 look-up sequence. In the presence of diamond inheritance patterns
365 it occasionally guesses wrong.
</p>
366 <p>It's also too slow (despite caching).
</p>
367 <p>Comment, suggestions, and patches welcome.
</p>
371 <h1><a name=
"copyright">COPYRIGHT
</a></h1>
373 Copyright (c)
2000-
2001, Damian Conway. All Rights Reserved.
374 This module is free software. It may be used, redistributed
375 and/or modified under the same terms as Perl itself.
377 <table border=
"0" width=
"100%" cellspacing=
"0" cellpadding=
"3">
378 <tr><td class=
"block" style=
"background-color: #cccccc" valign=
"middle">
379 <big><strong><span class=
"block"> NEXT.pm - Provide a pseudo-class NEXT that allows method redispatch
</span></strong></big>