xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/lib/NEXT.pm (revision 0:68f95e015346)
1*0Sstevel@tonic-gatepackage NEXT;
2*0Sstevel@tonic-gate$VERSION = '0.60';
3*0Sstevel@tonic-gateuse Carp;
4*0Sstevel@tonic-gateuse strict;
5*0Sstevel@tonic-gate
6*0Sstevel@tonic-gatesub NEXT::ELSEWHERE::ancestors
7*0Sstevel@tonic-gate{
8*0Sstevel@tonic-gate	my @inlist = shift;
9*0Sstevel@tonic-gate	my @outlist = ();
10*0Sstevel@tonic-gate	while (my $next = shift @inlist) {
11*0Sstevel@tonic-gate		push @outlist, $next;
12*0Sstevel@tonic-gate		no strict 'refs';
13*0Sstevel@tonic-gate		unshift @inlist, @{"$outlist[-1]::ISA"};
14*0Sstevel@tonic-gate	}
15*0Sstevel@tonic-gate	return @outlist;
16*0Sstevel@tonic-gate}
17*0Sstevel@tonic-gate
18*0Sstevel@tonic-gatesub NEXT::ELSEWHERE::ordered_ancestors
19*0Sstevel@tonic-gate{
20*0Sstevel@tonic-gate	my @inlist = shift;
21*0Sstevel@tonic-gate	my @outlist = ();
22*0Sstevel@tonic-gate	while (my $next = shift @inlist) {
23*0Sstevel@tonic-gate		push @outlist, $next;
24*0Sstevel@tonic-gate		no strict 'refs';
25*0Sstevel@tonic-gate		push @inlist, @{"$outlist[-1]::ISA"};
26*0Sstevel@tonic-gate	}
27*0Sstevel@tonic-gate	return sort { $a->isa($b) ? -1
28*0Sstevel@tonic-gate	            : $b->isa($a) ? +1
29*0Sstevel@tonic-gate	            :                0 } @outlist;
30*0Sstevel@tonic-gate}
31*0Sstevel@tonic-gate
32*0Sstevel@tonic-gatesub AUTOLOAD
33*0Sstevel@tonic-gate{
34*0Sstevel@tonic-gate	my ($self) = @_;
35*0Sstevel@tonic-gate	my $caller = (caller(1))[3];
36*0Sstevel@tonic-gate	my $wanted = $NEXT::AUTOLOAD || 'NEXT::AUTOLOAD';
37*0Sstevel@tonic-gate	undef $NEXT::AUTOLOAD;
38*0Sstevel@tonic-gate	my ($caller_class, $caller_method) = $caller =~ m{(.*)::(.*)}g;
39*0Sstevel@tonic-gate	my ($wanted_class, $wanted_method) = $wanted =~ m{(.*)::(.*)}g;
40*0Sstevel@tonic-gate	croak "Can't call $wanted from $caller"
41*0Sstevel@tonic-gate		unless $caller_method eq $wanted_method;
42*0Sstevel@tonic-gate
43*0Sstevel@tonic-gate	local ($NEXT::NEXT{$self,$wanted_method}, $NEXT::SEEN) =
44*0Sstevel@tonic-gate	      ($NEXT::NEXT{$self,$wanted_method}, $NEXT::SEEN);
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate
47*0Sstevel@tonic-gate	unless ($NEXT::NEXT{$self,$wanted_method}) {
48*0Sstevel@tonic-gate		my @forebears =
49*0Sstevel@tonic-gate			NEXT::ELSEWHERE::ancestors ref $self || $self,
50*0Sstevel@tonic-gate						   $wanted_class;
51*0Sstevel@tonic-gate		while (@forebears) {
52*0Sstevel@tonic-gate			last if shift @forebears eq $caller_class
53*0Sstevel@tonic-gate		}
54*0Sstevel@tonic-gate		no strict 'refs';
55*0Sstevel@tonic-gate		@{$NEXT::NEXT{$self,$wanted_method}} =
56*0Sstevel@tonic-gate			map { *{"${_}::$caller_method"}{CODE}||() } @forebears
57*0Sstevel@tonic-gate				unless $wanted_method eq 'AUTOLOAD';
58*0Sstevel@tonic-gate		@{$NEXT::NEXT{$self,$wanted_method}} =
59*0Sstevel@tonic-gate			map { (*{"${_}::AUTOLOAD"}{CODE}) ? "${_}::AUTOLOAD" : ()} @forebears
60*0Sstevel@tonic-gate				unless @{$NEXT::NEXT{$self,$wanted_method}||[]};
61*0Sstevel@tonic-gate		$NEXT::SEEN->{$self,*{$caller}{CODE}}++;
62*0Sstevel@tonic-gate	}
63*0Sstevel@tonic-gate	my $call_method = shift @{$NEXT::NEXT{$self,$wanted_method}};
64*0Sstevel@tonic-gate	while ($wanted_class =~ /^NEXT\b.*\b(UNSEEN|DISTINCT)\b/
65*0Sstevel@tonic-gate	       && defined $call_method
66*0Sstevel@tonic-gate	       && $NEXT::SEEN->{$self,$call_method}++) {
67*0Sstevel@tonic-gate		$call_method = shift @{$NEXT::NEXT{$self,$wanted_method}};
68*0Sstevel@tonic-gate	}
69*0Sstevel@tonic-gate	unless (defined $call_method) {
70*0Sstevel@tonic-gate		return unless $wanted_class =~ /^NEXT:.*:ACTUAL/;
71*0Sstevel@tonic-gate		(local $Carp::CarpLevel)++;
72*0Sstevel@tonic-gate		croak qq(Can't locate object method "$wanted_method" ),
73*0Sstevel@tonic-gate		      qq(via package "$caller_class");
74*0Sstevel@tonic-gate	};
75*0Sstevel@tonic-gate	return $self->$call_method(@_[1..$#_]) if ref $call_method eq 'CODE';
76*0Sstevel@tonic-gate	no strict 'refs';
77*0Sstevel@tonic-gate	($wanted_method=${$caller_class."::AUTOLOAD"}) =~ s/.*:://
78*0Sstevel@tonic-gate		if $wanted_method eq 'AUTOLOAD';
79*0Sstevel@tonic-gate	$$call_method = $caller_class."::NEXT::".$wanted_method;
80*0Sstevel@tonic-gate	return $call_method->(@_);
81*0Sstevel@tonic-gate}
82*0Sstevel@tonic-gate
83*0Sstevel@tonic-gateno strict 'vars';
84*0Sstevel@tonic-gatepackage NEXT::UNSEEN;		@ISA = 'NEXT';
85*0Sstevel@tonic-gatepackage NEXT::DISTINCT;		@ISA = 'NEXT';
86*0Sstevel@tonic-gatepackage NEXT::ACTUAL;		@ISA = 'NEXT';
87*0Sstevel@tonic-gatepackage NEXT::ACTUAL::UNSEEN;	@ISA = 'NEXT';
88*0Sstevel@tonic-gatepackage NEXT::ACTUAL::DISTINCT;	@ISA = 'NEXT';
89*0Sstevel@tonic-gatepackage NEXT::UNSEEN::ACTUAL;	@ISA = 'NEXT';
90*0Sstevel@tonic-gatepackage NEXT::DISTINCT::ACTUAL;	@ISA = 'NEXT';
91*0Sstevel@tonic-gate
92*0Sstevel@tonic-gatepackage EVERY::LAST;		@ISA = 'EVERY';
93*0Sstevel@tonic-gatepackage EVERY;			@ISA = 'NEXT';
94*0Sstevel@tonic-gatesub AUTOLOAD
95*0Sstevel@tonic-gate{
96*0Sstevel@tonic-gate	my ($self) = @_;
97*0Sstevel@tonic-gate	my $caller = (caller(1))[3];
98*0Sstevel@tonic-gate	my $wanted = $EVERY::AUTOLOAD || 'EVERY::AUTOLOAD';
99*0Sstevel@tonic-gate	undef $EVERY::AUTOLOAD;
100*0Sstevel@tonic-gate	my ($wanted_class, $wanted_method) = $wanted =~ m{(.*)::(.*)}g;
101*0Sstevel@tonic-gate
102*0Sstevel@tonic-gate	local $NEXT::ALREADY_IN_EVERY{$self,$wanted_method} =
103*0Sstevel@tonic-gate	      $NEXT::ALREADY_IN_EVERY{$self,$wanted_method};
104*0Sstevel@tonic-gate
105*0Sstevel@tonic-gate	return if $NEXT::ALREADY_IN_EVERY{$self,$wanted_method}++;
106*0Sstevel@tonic-gate
107*0Sstevel@tonic-gate	my @forebears = NEXT::ELSEWHERE::ordered_ancestors ref $self || $self,
108*0Sstevel@tonic-gate					                   $wanted_class;
109*0Sstevel@tonic-gate	@forebears = reverse @forebears if $wanted_class =~ /\bLAST\b/;
110*0Sstevel@tonic-gate	no strict 'refs';
111*0Sstevel@tonic-gate	my %seen;
112*0Sstevel@tonic-gate	my @every = map { my $sub = "${_}::$wanted_method";
113*0Sstevel@tonic-gate		          !*{$sub}{CODE} || $seen{$sub}++ ? () : $sub
114*0Sstevel@tonic-gate		        } @forebears
115*0Sstevel@tonic-gate				unless $wanted_method eq 'AUTOLOAD';
116*0Sstevel@tonic-gate
117*0Sstevel@tonic-gate	my $want = wantarray;
118*0Sstevel@tonic-gate	if (@every) {
119*0Sstevel@tonic-gate		if ($want) {
120*0Sstevel@tonic-gate			return map {($_, [$self->$_(@_[1..$#_])])} @every;
121*0Sstevel@tonic-gate		}
122*0Sstevel@tonic-gate		elsif (defined $want) {
123*0Sstevel@tonic-gate			return { map {($_, scalar($self->$_(@_[1..$#_])))}
124*0Sstevel@tonic-gate				     @every
125*0Sstevel@tonic-gate			       };
126*0Sstevel@tonic-gate		}
127*0Sstevel@tonic-gate		else {
128*0Sstevel@tonic-gate			$self->$_(@_[1..$#_]) for @every;
129*0Sstevel@tonic-gate			return;
130*0Sstevel@tonic-gate		}
131*0Sstevel@tonic-gate	}
132*0Sstevel@tonic-gate
133*0Sstevel@tonic-gate	@every = map { my $sub = "${_}::AUTOLOAD";
134*0Sstevel@tonic-gate		       !*{$sub}{CODE} || $seen{$sub}++ ? () : "${_}::AUTOLOAD"
135*0Sstevel@tonic-gate		     } @forebears;
136*0Sstevel@tonic-gate	if ($want) {
137*0Sstevel@tonic-gate		return map { $$_ = ref($self)."::EVERY::".$wanted_method;
138*0Sstevel@tonic-gate			     ($_, [$self->$_(@_[1..$#_])]);
139*0Sstevel@tonic-gate			   } @every;
140*0Sstevel@tonic-gate	}
141*0Sstevel@tonic-gate	elsif (defined $want) {
142*0Sstevel@tonic-gate		return { map { $$_ = ref($self)."::EVERY::".$wanted_method;
143*0Sstevel@tonic-gate			       ($_, scalar($self->$_(@_[1..$#_])))
144*0Sstevel@tonic-gate			     } @every
145*0Sstevel@tonic-gate		       };
146*0Sstevel@tonic-gate	}
147*0Sstevel@tonic-gate	else {
148*0Sstevel@tonic-gate		for (@every) {
149*0Sstevel@tonic-gate			$$_ = ref($self)."::EVERY::".$wanted_method;
150*0Sstevel@tonic-gate			$self->$_(@_[1..$#_]);
151*0Sstevel@tonic-gate		}
152*0Sstevel@tonic-gate		return;
153*0Sstevel@tonic-gate	}
154*0Sstevel@tonic-gate}
155*0Sstevel@tonic-gate
156*0Sstevel@tonic-gate
157*0Sstevel@tonic-gate1;
158*0Sstevel@tonic-gate
159*0Sstevel@tonic-gate__END__
160*0Sstevel@tonic-gate
161*0Sstevel@tonic-gate=head1 NAME
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gateNEXT.pm - Provide a pseudo-class NEXT (et al) that allows method redispatch
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate
166*0Sstevel@tonic-gate=head1 SYNOPSIS
167*0Sstevel@tonic-gate
168*0Sstevel@tonic-gate    use NEXT;
169*0Sstevel@tonic-gate
170*0Sstevel@tonic-gate    package A;
171*0Sstevel@tonic-gate    sub A::method   { print "$_[0]: A method\n";   $_[0]->NEXT::method() }
172*0Sstevel@tonic-gate    sub A::DESTROY  { print "$_[0]: A dtor\n";     $_[0]->NEXT::DESTROY() }
173*0Sstevel@tonic-gate
174*0Sstevel@tonic-gate    package B;
175*0Sstevel@tonic-gate    use base qw( A );
176*0Sstevel@tonic-gate    sub B::AUTOLOAD { print "$_[0]: B AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
177*0Sstevel@tonic-gate    sub B::DESTROY  { print "$_[0]: B dtor\n";     $_[0]->NEXT::DESTROY() }
178*0Sstevel@tonic-gate
179*0Sstevel@tonic-gate    package C;
180*0Sstevel@tonic-gate    sub C::method   { print "$_[0]: C method\n";   $_[0]->NEXT::method() }
181*0Sstevel@tonic-gate    sub C::AUTOLOAD { print "$_[0]: C AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
182*0Sstevel@tonic-gate    sub C::DESTROY  { print "$_[0]: C dtor\n";     $_[0]->NEXT::DESTROY() }
183*0Sstevel@tonic-gate
184*0Sstevel@tonic-gate    package D;
185*0Sstevel@tonic-gate    use base qw( B C );
186*0Sstevel@tonic-gate    sub D::method   { print "$_[0]: D method\n";   $_[0]->NEXT::method() }
187*0Sstevel@tonic-gate    sub D::AUTOLOAD { print "$_[0]: D AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
188*0Sstevel@tonic-gate    sub D::DESTROY  { print "$_[0]: D dtor\n";     $_[0]->NEXT::DESTROY() }
189*0Sstevel@tonic-gate
190*0Sstevel@tonic-gate    package main;
191*0Sstevel@tonic-gate
192*0Sstevel@tonic-gate    my $obj = bless {}, "D";
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gate    $obj->method();		# Calls D::method, A::method, C::method
195*0Sstevel@tonic-gate    $obj->missing_method(); # Calls D::AUTOLOAD, B::AUTOLOAD, C::AUTOLOAD
196*0Sstevel@tonic-gate
197*0Sstevel@tonic-gate    # Clean-up calls D::DESTROY, B::DESTROY, A::DESTROY, C::DESTROY
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate
200*0Sstevel@tonic-gate
201*0Sstevel@tonic-gate=head1 DESCRIPTION
202*0Sstevel@tonic-gate
203*0Sstevel@tonic-gateNEXT.pm adds a pseudoclass named C<NEXT> to any program
204*0Sstevel@tonic-gatethat uses it. If a method C<m> calls C<$self-E<gt>NEXT::m()>, the call to
205*0Sstevel@tonic-gateC<m> is redispatched as if the calling method had not originally been found.
206*0Sstevel@tonic-gate
207*0Sstevel@tonic-gateIn other words, a call to C<$self-E<gt>NEXT::m()> resumes the depth-first,
208*0Sstevel@tonic-gateleft-to-right search of C<$self>'s class hierarchy that resulted in the
209*0Sstevel@tonic-gateoriginal call to C<m>.
210*0Sstevel@tonic-gate
211*0Sstevel@tonic-gateNote that this is not the same thing as C<$self-E<gt>SUPER::m()>, which
212*0Sstevel@tonic-gatebegins a new dispatch that is restricted to searching the ancestors
213*0Sstevel@tonic-gateof the current class. C<$self-E<gt>NEXT::m()> can backtrack
214*0Sstevel@tonic-gatepast the current class -- to look for a suitable method in other
215*0Sstevel@tonic-gateancestors of C<$self> -- whereas C<$self-E<gt>SUPER::m()> cannot.
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gateA typical use would be in the destructors of a class hierarchy,
218*0Sstevel@tonic-gateas illustrated in the synopsis above. Each class in the hierarchy
219*0Sstevel@tonic-gatehas a DESTROY method that performs some class-specific action
220*0Sstevel@tonic-gateand then redispatches the call up the hierarchy. As a result,
221*0Sstevel@tonic-gatewhen an object of class D is destroyed, the destructors of I<all>
222*0Sstevel@tonic-gateits parent classes are called (in depth-first, left-to-right order).
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gateAnother typical use of redispatch would be in C<AUTOLOAD>'ed methods.
225*0Sstevel@tonic-gateIf such a method determined that it was not able to handle a
226*0Sstevel@tonic-gateparticular call, it might choose to redispatch that call, in the
227*0Sstevel@tonic-gatehope that some other C<AUTOLOAD> (above it, or to its left) might
228*0Sstevel@tonic-gatedo better.
229*0Sstevel@tonic-gate
230*0Sstevel@tonic-gateBy default, if a redispatch attempt fails to find another method
231*0Sstevel@tonic-gateelsewhere in the objects class hierarchy, it quietly gives up and does
232*0Sstevel@tonic-gatenothing (but see L<"Enforcing redispatch">). This gracious acquiesence
233*0Sstevel@tonic-gateis also unlike the (generally annoying) behaviour of C<SUPER>, which
234*0Sstevel@tonic-gatethrows an exception if it cannot redispatch.
235*0Sstevel@tonic-gate
236*0Sstevel@tonic-gateNote that it is a fatal error for any method (including C<AUTOLOAD>)
237*0Sstevel@tonic-gateto attempt to redispatch any method that does not have the
238*0Sstevel@tonic-gatesame name. For example:
239*0Sstevel@tonic-gate
240*0Sstevel@tonic-gate        sub D::oops { print "oops!\n"; $_[0]->NEXT::other_method() }
241*0Sstevel@tonic-gate
242*0Sstevel@tonic-gate
243*0Sstevel@tonic-gate=head2 Enforcing redispatch
244*0Sstevel@tonic-gate
245*0Sstevel@tonic-gateIt is possible to make C<NEXT> redispatch more demandingly (i.e. like
246*0Sstevel@tonic-gateC<SUPER> does), so that the redispatch throws an exception if it cannot
247*0Sstevel@tonic-gatefind a "next" method to call.
248*0Sstevel@tonic-gate
249*0Sstevel@tonic-gateTo do this, simple invoke the redispatch as:
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate	$self->NEXT::ACTUAL::method();
252*0Sstevel@tonic-gate
253*0Sstevel@tonic-gaterather than:
254*0Sstevel@tonic-gate
255*0Sstevel@tonic-gate	$self->NEXT::method();
256*0Sstevel@tonic-gate
257*0Sstevel@tonic-gateThe C<ACTUAL> tells C<NEXT> that there must actually be a next method to call,
258*0Sstevel@tonic-gateor it should throw an exception.
259*0Sstevel@tonic-gate
260*0Sstevel@tonic-gateC<NEXT::ACTUAL> is most commonly used in C<AUTOLOAD> methods, as a means to
261*0Sstevel@tonic-gatedecline an C<AUTOLOAD> request, but preserve the normal exception-on-failure
262*0Sstevel@tonic-gatesemantics:
263*0Sstevel@tonic-gate
264*0Sstevel@tonic-gate	sub AUTOLOAD {
265*0Sstevel@tonic-gate		if ($AUTOLOAD =~ /foo|bar/) {
266*0Sstevel@tonic-gate			# handle here
267*0Sstevel@tonic-gate		}
268*0Sstevel@tonic-gate		else {  # try elsewhere
269*0Sstevel@tonic-gate			shift()->NEXT::ACTUAL::AUTOLOAD(@_);
270*0Sstevel@tonic-gate		}
271*0Sstevel@tonic-gate	}
272*0Sstevel@tonic-gate
273*0Sstevel@tonic-gateBy using C<NEXT::ACTUAL>, if there is no other C<AUTOLOAD> to handle the
274*0Sstevel@tonic-gatemethod call, an exception will be thrown (as usually happens in the absence of
275*0Sstevel@tonic-gatea suitable C<AUTOLOAD>).
276*0Sstevel@tonic-gate
277*0Sstevel@tonic-gate
278*0Sstevel@tonic-gate=head2 Avoiding repetitions
279*0Sstevel@tonic-gate
280*0Sstevel@tonic-gateIf C<NEXT> redispatching is used in the methods of a "diamond" class hierarchy:
281*0Sstevel@tonic-gate
282*0Sstevel@tonic-gate	#     A   B
283*0Sstevel@tonic-gate	#    / \ /
284*0Sstevel@tonic-gate	#   C   D
285*0Sstevel@tonic-gate	#    \ /
286*0Sstevel@tonic-gate	#     E
287*0Sstevel@tonic-gate
288*0Sstevel@tonic-gate	use NEXT;
289*0Sstevel@tonic-gate
290*0Sstevel@tonic-gate	package A;
291*0Sstevel@tonic-gate	sub foo { print "called A::foo\n"; shift->NEXT::foo() }
292*0Sstevel@tonic-gate
293*0Sstevel@tonic-gate	package B;
294*0Sstevel@tonic-gate	sub foo { print "called B::foo\n"; shift->NEXT::foo() }
295*0Sstevel@tonic-gate
296*0Sstevel@tonic-gate	package C; @ISA = qw( A );
297*0Sstevel@tonic-gate	sub foo { print "called C::foo\n"; shift->NEXT::foo() }
298*0Sstevel@tonic-gate
299*0Sstevel@tonic-gate	package D; @ISA = qw(A B);
300*0Sstevel@tonic-gate	sub foo { print "called D::foo\n"; shift->NEXT::foo() }
301*0Sstevel@tonic-gate
302*0Sstevel@tonic-gate	package E; @ISA = qw(C D);
303*0Sstevel@tonic-gate	sub foo { print "called E::foo\n"; shift->NEXT::foo() }
304*0Sstevel@tonic-gate
305*0Sstevel@tonic-gate	E->foo();
306*0Sstevel@tonic-gate
307*0Sstevel@tonic-gatethen derived classes may (re-)inherit base-class methods through two or
308*0Sstevel@tonic-gatemore distinct paths (e.g. in the way C<E> inherits C<A::foo> twice --
309*0Sstevel@tonic-gatethrough C<C> and C<D>). In such cases, a sequence of C<NEXT> redispatches
310*0Sstevel@tonic-gatewill invoke the multiply inherited method as many times as it is
311*0Sstevel@tonic-gateinherited. For example, the above code prints:
312*0Sstevel@tonic-gate
313*0Sstevel@tonic-gate        called E::foo
314*0Sstevel@tonic-gate        called C::foo
315*0Sstevel@tonic-gate        called A::foo
316*0Sstevel@tonic-gate        called D::foo
317*0Sstevel@tonic-gate        called A::foo
318*0Sstevel@tonic-gate        called B::foo
319*0Sstevel@tonic-gate
320*0Sstevel@tonic-gate(i.e. C<A::foo> is called twice).
321*0Sstevel@tonic-gate
322*0Sstevel@tonic-gateIn some cases this I<may> be the desired effect within a diamond hierarchy,
323*0Sstevel@tonic-gatebut in others (e.g. for destructors) it may be more appropriate to
324*0Sstevel@tonic-gatecall each method only once during a sequence of redispatches.
325*0Sstevel@tonic-gate
326*0Sstevel@tonic-gateTo cover such cases, you can redispatch methods via:
327*0Sstevel@tonic-gate
328*0Sstevel@tonic-gate        $self->NEXT::DISTINCT::method();
329*0Sstevel@tonic-gate
330*0Sstevel@tonic-gaterather than:
331*0Sstevel@tonic-gate
332*0Sstevel@tonic-gate        $self->NEXT::method();
333*0Sstevel@tonic-gate
334*0Sstevel@tonic-gateThis causes the redispatcher to only visit each distinct C<method> method
335*0Sstevel@tonic-gateonce. That is, to skip any classes in the hierarchy that it has
336*0Sstevel@tonic-gatealready visited during redispatch. So, for example, if the
337*0Sstevel@tonic-gateprevious example were rewritten:
338*0Sstevel@tonic-gate
339*0Sstevel@tonic-gate        package A;
340*0Sstevel@tonic-gate        sub foo { print "called A::foo\n"; shift->NEXT::DISTINCT::foo() }
341*0Sstevel@tonic-gate
342*0Sstevel@tonic-gate        package B;
343*0Sstevel@tonic-gate        sub foo { print "called B::foo\n"; shift->NEXT::DISTINCT::foo() }
344*0Sstevel@tonic-gate
345*0Sstevel@tonic-gate        package C; @ISA = qw( A );
346*0Sstevel@tonic-gate        sub foo { print "called C::foo\n"; shift->NEXT::DISTINCT::foo() }
347*0Sstevel@tonic-gate
348*0Sstevel@tonic-gate        package D; @ISA = qw(A B);
349*0Sstevel@tonic-gate        sub foo { print "called D::foo\n"; shift->NEXT::DISTINCT::foo() }
350*0Sstevel@tonic-gate
351*0Sstevel@tonic-gate        package E; @ISA = qw(C D);
352*0Sstevel@tonic-gate        sub foo { print "called E::foo\n"; shift->NEXT::DISTINCT::foo() }
353*0Sstevel@tonic-gate
354*0Sstevel@tonic-gate        E->foo();
355*0Sstevel@tonic-gate
356*0Sstevel@tonic-gatethen it would print:
357*0Sstevel@tonic-gate
358*0Sstevel@tonic-gate        called E::foo
359*0Sstevel@tonic-gate        called C::foo
360*0Sstevel@tonic-gate        called A::foo
361*0Sstevel@tonic-gate        called D::foo
362*0Sstevel@tonic-gate        called B::foo
363*0Sstevel@tonic-gate
364*0Sstevel@tonic-gateand omit the second call to C<A::foo> (since it would not be distinct
365*0Sstevel@tonic-gatefrom the first call to C<A::foo>).
366*0Sstevel@tonic-gate
367*0Sstevel@tonic-gateNote that you can also use:
368*0Sstevel@tonic-gate
369*0Sstevel@tonic-gate        $self->NEXT::DISTINCT::ACTUAL::method();
370*0Sstevel@tonic-gate
371*0Sstevel@tonic-gateor:
372*0Sstevel@tonic-gate
373*0Sstevel@tonic-gate        $self->NEXT::ACTUAL::DISTINCT::method();
374*0Sstevel@tonic-gate
375*0Sstevel@tonic-gateto get both unique invocation I<and> exception-on-failure.
376*0Sstevel@tonic-gate
377*0Sstevel@tonic-gateNote that, for historical compatibility, you can also use
378*0Sstevel@tonic-gateC<NEXT::UNSEEN> instead of C<NEXT::DISTINCT>.
379*0Sstevel@tonic-gate
380*0Sstevel@tonic-gate
381*0Sstevel@tonic-gate=head2 Invoking all versions of a method with a single call
382*0Sstevel@tonic-gate
383*0Sstevel@tonic-gateYet another pseudo-class that NEXT.pm provides is C<EVERY>.
384*0Sstevel@tonic-gateIts behaviour is considerably simpler than that of the C<NEXT> family.
385*0Sstevel@tonic-gateA call to:
386*0Sstevel@tonic-gate
387*0Sstevel@tonic-gate	$obj->EVERY::foo();
388*0Sstevel@tonic-gate
389*0Sstevel@tonic-gatecalls I<every> method named C<foo> that the object in C<$obj> has inherited.
390*0Sstevel@tonic-gateThat is:
391*0Sstevel@tonic-gate
392*0Sstevel@tonic-gate	use NEXT;
393*0Sstevel@tonic-gate
394*0Sstevel@tonic-gate	package A; @ISA = qw(B D X);
395*0Sstevel@tonic-gate	sub foo { print "A::foo " }
396*0Sstevel@tonic-gate
397*0Sstevel@tonic-gate	package B; @ISA = qw(D X);
398*0Sstevel@tonic-gate	sub foo { print "B::foo " }
399*0Sstevel@tonic-gate
400*0Sstevel@tonic-gate	package X; @ISA = qw(D);
401*0Sstevel@tonic-gate	sub foo { print "X::foo " }
402*0Sstevel@tonic-gate
403*0Sstevel@tonic-gate	package D;
404*0Sstevel@tonic-gate	sub foo { print "D::foo " }
405*0Sstevel@tonic-gate
406*0Sstevel@tonic-gate	package main;
407*0Sstevel@tonic-gate
408*0Sstevel@tonic-gate	my $obj = bless {}, 'A';
409*0Sstevel@tonic-gate	$obj->EVERY::foo();        # prints" A::foo B::foo X::foo D::foo
410*0Sstevel@tonic-gate
411*0Sstevel@tonic-gatePrefixing a method call with C<EVERY::> causes every method in the
412*0Sstevel@tonic-gateobject's hierarchy with that name to be invoked. As the above example
413*0Sstevel@tonic-gateillustrates, they are not called in Perl's usual "left-most-depth-first"
414*0Sstevel@tonic-gateorder. Instead, they are called "breadth-first-dependency-wise".
415*0Sstevel@tonic-gate
416*0Sstevel@tonic-gateThat means that the inheritance tree of the object is traversed breadth-first
417*0Sstevel@tonic-gateand the resulting order of classes is used as the sequence in which methods
418*0Sstevel@tonic-gateare called. However, that sequence is modified by imposing a rule that the
419*0Sstevel@tonic-gateappropritae method of a derived class must be called before the same method of
420*0Sstevel@tonic-gateany ancestral class. That's why, in the above example, C<X::foo> is called
421*0Sstevel@tonic-gatebefore C<D::foo>, even though C<D> comes before C<X> in C<@B::ISA>.
422*0Sstevel@tonic-gate
423*0Sstevel@tonic-gateIn general, there's no need to worry about the order of calls. They will be
424*0Sstevel@tonic-gateleft-to-right, breadth-first, most-derived-first. This works perfectly for
425*0Sstevel@tonic-gatemost inherited methods (including destructors), but is inappropriate for
426*0Sstevel@tonic-gatesome kinds of methods (such as constructors, cloners, debuggers, and
427*0Sstevel@tonic-gateinitializers) where it's more appropriate that the least-derived methods be
428*0Sstevel@tonic-gatecalled first (as more-derived methods may rely on the behaviour of their
429*0Sstevel@tonic-gate"ancestors"). In that case, instead of using the C<EVERY> pseudo-class:
430*0Sstevel@tonic-gate
431*0Sstevel@tonic-gate	$obj->EVERY::foo();        # prints" A::foo B::foo X::foo D::foo
432*0Sstevel@tonic-gate
433*0Sstevel@tonic-gateyou can use the C<EVERY::LAST> pseudo-class:
434*0Sstevel@tonic-gate
435*0Sstevel@tonic-gate	$obj->EVERY::LAST::foo();  # prints" D::foo X::foo B::foo A::foo
436*0Sstevel@tonic-gate
437*0Sstevel@tonic-gatewhich reverses the order of method call.
438*0Sstevel@tonic-gate
439*0Sstevel@tonic-gateWhichever version is used, the actual methods are called in the same
440*0Sstevel@tonic-gatecontext (list, scalar, or void) as the original call via C<EVERY>, and return:
441*0Sstevel@tonic-gate
442*0Sstevel@tonic-gate=over
443*0Sstevel@tonic-gate
444*0Sstevel@tonic-gate=item *
445*0Sstevel@tonic-gate
446*0Sstevel@tonic-gateA hash of array references in list context. Each entry of the hash has the
447*0Sstevel@tonic-gatefully qualified method name as its key and a reference to an array containing
448*0Sstevel@tonic-gatethe method's list-context return values as its value.
449*0Sstevel@tonic-gate
450*0Sstevel@tonic-gate=item *
451*0Sstevel@tonic-gate
452*0Sstevel@tonic-gateA reference to a hash of scalar values in scalar context. Each entry of the hash has the
453*0Sstevel@tonic-gatefully qualified method name as its key and the method's scalar-context return values as its value.
454*0Sstevel@tonic-gate
455*0Sstevel@tonic-gate=item *
456*0Sstevel@tonic-gate
457*0Sstevel@tonic-gateNothing in void context (obviously).
458*0Sstevel@tonic-gate
459*0Sstevel@tonic-gate=back
460*0Sstevel@tonic-gate
461*0Sstevel@tonic-gate=head2 Using C<EVERY> methods
462*0Sstevel@tonic-gate
463*0Sstevel@tonic-gateThe typical way to use an C<EVERY> call is to wrap it in another base
464*0Sstevel@tonic-gatemethod, that all classes inherit. For example, to ensure that every
465*0Sstevel@tonic-gatedestructor an object inherits is actually called (as opposed to just the
466*0Sstevel@tonic-gateleft-most-depth-first-est one):
467*0Sstevel@tonic-gate
468*0Sstevel@tonic-gate        package Base;
469*0Sstevel@tonic-gate        sub DESTROY { $_[0]->EVERY::Destroy }
470*0Sstevel@tonic-gate
471*0Sstevel@tonic-gate        package Derived1;
472*0Sstevel@tonic-gate        use base 'Base';
473*0Sstevel@tonic-gate        sub Destroy {...}
474*0Sstevel@tonic-gate
475*0Sstevel@tonic-gate        package Derived2;
476*0Sstevel@tonic-gate        use base 'Base', 'Derived1';
477*0Sstevel@tonic-gate        sub Destroy {...}
478*0Sstevel@tonic-gate
479*0Sstevel@tonic-gateet cetera. Every derived class than needs its own clean-up
480*0Sstevel@tonic-gatebehaviour simply adds its own C<Destroy> method (I<not> a C<DESTROY> method),
481*0Sstevel@tonic-gatewhich the call to C<EVERY::LAST::Destroy> in the inherited destructor
482*0Sstevel@tonic-gatethen correctly picks up.
483*0Sstevel@tonic-gate
484*0Sstevel@tonic-gateLikewise, to create a class hierarchy in which every initializer inherited by
485*0Sstevel@tonic-gatea new object is invoked:
486*0Sstevel@tonic-gate
487*0Sstevel@tonic-gate        package Base;
488*0Sstevel@tonic-gate        sub new {
489*0Sstevel@tonic-gate		my ($class, %args) = @_;
490*0Sstevel@tonic-gate		my $obj = bless {}, $class;
491*0Sstevel@tonic-gate		$obj->EVERY::LAST::Init(\%args);
492*0Sstevel@tonic-gate	}
493*0Sstevel@tonic-gate
494*0Sstevel@tonic-gate        package Derived1;
495*0Sstevel@tonic-gate        use base 'Base';
496*0Sstevel@tonic-gate        sub Init {
497*0Sstevel@tonic-gate		my ($argsref) = @_;
498*0Sstevel@tonic-gate		...
499*0Sstevel@tonic-gate	}
500*0Sstevel@tonic-gate
501*0Sstevel@tonic-gate        package Derived2;
502*0Sstevel@tonic-gate        use base 'Base', 'Derived1';
503*0Sstevel@tonic-gate        sub Init {
504*0Sstevel@tonic-gate		my ($argsref) = @_;
505*0Sstevel@tonic-gate		...
506*0Sstevel@tonic-gate	}
507*0Sstevel@tonic-gate
508*0Sstevel@tonic-gateet cetera. Every derived class than needs some additional initialization
509*0Sstevel@tonic-gatebehaviour simply adds its own C<Init> method (I<not> a C<new> method),
510*0Sstevel@tonic-gatewhich the call to C<EVERY::LAST::Init> in the inherited constructor
511*0Sstevel@tonic-gatethen correctly picks up.
512*0Sstevel@tonic-gate
513*0Sstevel@tonic-gate
514*0Sstevel@tonic-gate=head1 AUTHOR
515*0Sstevel@tonic-gate
516*0Sstevel@tonic-gateDamian Conway (damian@conway.org)
517*0Sstevel@tonic-gate
518*0Sstevel@tonic-gate=head1 BUGS AND IRRITATIONS
519*0Sstevel@tonic-gate
520*0Sstevel@tonic-gateBecause it's a module, not an integral part of the interpreter, NEXT.pm
521*0Sstevel@tonic-gatehas to guess where the surrounding call was found in the method
522*0Sstevel@tonic-gatelook-up sequence. In the presence of diamond inheritance patterns
523*0Sstevel@tonic-gateit occasionally guesses wrong.
524*0Sstevel@tonic-gate
525*0Sstevel@tonic-gateIt's also too slow (despite caching).
526*0Sstevel@tonic-gate
527*0Sstevel@tonic-gateComment, suggestions, and patches welcome.
528*0Sstevel@tonic-gate
529*0Sstevel@tonic-gate=head1 COPYRIGHT
530*0Sstevel@tonic-gate
531*0Sstevel@tonic-gate Copyright (c) 2000-2001, Damian Conway. All Rights Reserved.
532*0Sstevel@tonic-gate This module is free software. It may be used, redistributed
533*0Sstevel@tonic-gate    and/or modified under the same terms as Perl itself.
534