NEXT(3pm)
π NAME π
okay so this is NEXT(3pm), straight out of the Perl Programmers Reference Guide, and the name is literally NEXT β Provide a pseudo-class NEXT (et al) that allows method redispatch. That's the whole assignment, bestie. No cap. π«Άβ¨
β¨ SYNOPSIS β¨
bestie, here's the vibe in code β use NEXT; and then the packages do their little redispatch dance. Every line is doing main character work π
:
use NEXT;
package P;
sub P::method { print "$_[0]: P method\n"; $_[0]->NEXT::method() }
sub P::DESTROY { print "$_[0]: P dtor\n"; $_[0]->NEXT::DESTROY() }
package Q;
use base qw( P );
sub Q::AUTOLOAD { print "$_[0]: Q AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
sub Q::DESTROY { print "$_[0]: Q dtor\n"; $_[0]->NEXT::DESTROY() }
package R;
sub R::method { print "$_[0]: R method\n"; $_[0]->NEXT::method() }
sub R::AUTOLOAD { print "$_[0]: R AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
sub R::DESTROY { print "$_[0]: R dtor\n"; $_[0]->NEXT::DESTROY() }
package S;
use base qw( Q R );
sub S::method { print "$_[0]: S method\n"; $_[0]->NEXT::method() }
sub S::AUTOLOAD { print "$_[0]: S AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
sub S::DESTROY { print "$_[0]: S dtor\n"; $_[0]->NEXT::DESTROY() }
package main;
my $obj = bless {}, "S";
$obj->method(); # Calls S::method, P::method, R::method
$obj->missing_method(); # Calls S::AUTOLOAD, Q::AUTOLOAD, R::AUTOLOAD
# Clean-up calls S::DESTROY, Q::DESTROY, P::DESTROY, R::DESTROY
π DESCRIPTION π
Okay bestie, so here's the tea: the NEXT module just casually adds a pseudoclass named NEXT to any program that uses it. That's it. That's the whole vibe. So if a method m calls $self->NEXT::m(), then that call to m gets redispatched as if the calling method had never been found in the first place. Iconic behavior, honestly.
π«Ά Note before you go any further: you should lowkey look atnext::method<https://metacpan.org/pod/mro#next::method> in the coremromodule first.mrohas been a core module since Perl 5.9.5, so there's genuinely no excuse. β¨
In other words β and I need you to hear this β a call to $self->NEXT::m() resumes the depth-first, left-to-right search of $self's class hierarchy that resulted in the original call to m. It's literally picking up right where things left off. π
And no, before you ask, this is not the same thing as $self->SUPER::m(). SUPER starts a brand new dispatch that's restricted to searching the ancestors of the current class. $self->NEXT::m(), on the other hand, can backtrack past the current class β looking for a suitable method in other ancestors of $self β whereas $self->SUPER::m() simply cannot do that. It's giving "sorry bestie, that's outside my jurisdiction." π
A typical use would be in the destructors of a class hierarchy, exactly like the one illustrated in the SYNOPSIS above. Every class in the hierarchy has a DESTROY method that does some class-specific little task and then redispatches the call up the hierarchy. Result? When an object of class S is destroyed, the destructors of all its parent classes get called (in depth-first, left-to-right order). Every single one. Nobody gets left on read. π₯
Another super typical use of redispatch is in AUTOLOAD'ed methods. If one of those methods figures out it can't handle a particular call, it might choose to redispatch that call, hoping some other AUTOLOAD (above it, or to its left) will do better. Passing the aux, basically. π
By default, if a redispatch attempt fails to find another method elsewhere in the object's class hierarchy, it quietly gives up and does absolutely nothing (but do see "Enforcing redispatch" below, bestie). This gracious acquiescence is also unlike the (generally annoying) behaviour of SUPER, which throws an exception if it cannot redispatch. SUPER is that friend who makes it everyone's problem. π
Okay now the serious bit β no cap: it is a fatal error for any method (including AUTOLOAD) to attempt to redispatch any method that does not have the same name. Like, genuinely fatal. For example:
sub S::oops { print "oops!\n"; $_[0]->NEXT::other_method() }
π¦ Enforcing redispatch π¦
So you can make NEXT redispatch more demandingly (i.e. the way SUPER does it), so that the redispatch throws an exception if it can't find a "next" method to call. Main character energy, honestly.
To do this, simply invoke the redispatch as:
$self->NEXT::ACTUAL::method();
rather than:
$self->NEXT::method();
The ACTUAL is basically telling NEXT "bestie, there must actually be a next method to call, or throw an exception." Periodt.
NEXT::ACTUAL is most commonly used in AUTOLOAD methods, as a means to decline an AUTOLOAD request but preserve the normal exception-on-failure semantics:
sub AUTOLOAD {
if ($AUTOLOAD =~ /foo|bar/) {
# handle here
}
else { # try elsewhere
shift()->NEXT::ACTUAL::AUTOLOAD(@_);
}
}
By using NEXT::ACTUAL, if there's no other AUTOLOAD to handle the method call, an exception will be thrown (as usually happens when there's no suitable AUTOLOAD at all). No silent ghosting. π
π Avoiding repetitions π
Okay so here's a scenario. If NEXT redispatching is used in the methods of a "diamond" class hierarchy:
# A B
# / \ /
# C D
# \ /
# E
use NEXT;
package A;
sub foo { print "called A::foo\n"; shift->NEXT::foo() }
package B;
sub foo { print "called B::foo\n"; shift->NEXT::foo() }
package C; @ISA = qw( A );
sub foo { print "called C::foo\n"; shift->NEXT::foo() }
package D; @ISA = qw(A B);
sub foo { print "called D::foo\n"; shift->NEXT::foo() }
package E; @ISA = qw(C D);
sub foo { print "called E::foo\n"; shift->NEXT::foo() }
E->foo();
then derived classes may (re-)inherit base-class methods through two or more distinct paths β like how E inherits A::foo twice, once through C and once through D. In such cases, a sequence of NEXT redispatches will invoke the multiply inherited method as many times as it is inherited. So the above code prints:
called E::foo
called C::foo
called A::foo
called D::foo
called A::foo
called B::foo
(i.e. A::foo is called twice). Not me getting dΓ©jΓ vu π«
In some cases this may be exactly the desired effect within a diamond hierarchy β but in others (e.g. for destructors) it may be way more appropriate to call each method only once during a sequence of redispatches.
To cover such cases, you can redispatch methods via:
$self->NEXT::DISTINCT::method();
rather than:
$self->NEXT::method();
This causes the redispatcher to only visit each distinct method method once. That is, it skips any classes in the hierarchy it has already visited during redispatch. So if the previous example were rewritten:
package A;
sub foo { print "called A::foo\n"; shift->NEXT::DISTINCT::foo() }
package B;
sub foo { print "called B::foo\n"; shift->NEXT::DISTINCT::foo() }
package C; @ISA = qw( A );
sub foo { print "called C::foo\n"; shift->NEXT::DISTINCT::foo() }
package D; @ISA = qw(A B);
sub foo { print "called D::foo\n"; shift->NEXT::DISTINCT::foo() }
package E; @ISA = qw(C D);
sub foo { print "called E::foo\n"; shift->NEXT::DISTINCT::foo() }
E->foo();
then it would print:
called E::foo
called C::foo
called A::foo
called D::foo
called B::foo
and omit the second call to A::foo (since it wouldn't be distinct from the first call to A::foo). Slay, no duplicates. β¨
Note that you can also use:
$self->NEXT::DISTINCT::ACTUAL::method();
or:
$self->NEXT::ACTUAL::DISTINCT::method();
to get both unique invocation and exception-on-failure. Both flavors, bestie. π
Note that, for historical compatibility, you can also use NEXT::UNSEEN instead of NEXT::DISTINCT. Vintage iykyk. π
π Invoking all versions of a method with a single call π
Yet another pseudo-class that NEXT provides is EVERY. Its behaviour is considerably simpler than that of the NEXT family β honestly, lowkey a relief. A call to:
$obj->EVERY::foo();
calls every method named foo that the object in $obj has inherited. That is:
use NEXT;
package A; @ISA = qw(B D X);
sub foo { print "A::foo " }
package B; @ISA = qw(D X);
sub foo { print "B::foo " }
package X; @ISA = qw(D);
sub foo { print "X::foo " }
package D;
sub foo { print "D::foo " }
package main;
my $obj = bless {}, 'A';
$obj->EVERY::foo(); # prints" A::foo B::foo X::foo D::foo
Prefixing a method call with EVERY:: causes every method in the object's hierarchy with that name to be invoked. And as the example above shows, they are not called in Perl's usual "left-most-depth-first" order. Instead, they're called "breadth-first-dependency-wise". Fancy, right? π§
That means the inheritance tree of the object is traversed breadth-first, and the resulting order of classes becomes the sequence in which methods are called. However β plot twist β that sequence gets modified by a rule that the appropriate method of a derived class must be called before the same method of any ancestral class. That's why, in the example above, X::foo is called before D::foo, even though D comes before X in @B::ISA. Rules are rules. π
In general, there's no need to worry about the order of calls. They'll be left-to-right, breadth-first, most-derived-first. This works perfectly for most inherited methods (including destructors), but it's inappropriate for some kinds of methods (such as constructors, cloners, debuggers, and initializers) where it's more appropriate that the least-derived methods be called first β since more-derived methods may rely on the behaviour of their "ancestors". So in that case, instead of using the EVERY pseudo-class:
$obj->EVERY::foo(); # prints" A::foo B::foo X::foo D::foo
you can use the EVERY::LAST pseudo-class:
$obj->EVERY::LAST::foo(); # prints" D::foo X::foo B::foo A::foo
which reverses the order of method call. Literally just flip it. π
Whichever version is used, the actual methods are called in the same context (list, scalar, or void) as the original call via EVERY, and they return:
- A hash of array references in list context. Each entry of the hash has the fully qualified method name as its key and a reference to an array containing the method's list-context return values as its value. π
- A reference to a hash of scalar values in scalar context. Each entry of the hash has the fully qualified method name as its key and the method's scalar-context return values as its value. π
- Nothing in void context (obviously). π
πΈ Using EVERY methods πΈ
The typical way to use an EVERY call is to wrap it in another base method that all classes inherit. For example, to ensure that every destructor an object inherits is actually called (as opposed to just the left-most-depth-first-est one):
package Base;
sub DESTROY { $_[0]->EVERY::Destroy }
package Derived1;
use base 'Base';
sub Destroy {...}
package Derived2;
use base 'Base', 'Derived1';
sub Destroy {...}
et cetera. Every derived class that needs its own clean-up behaviour simply adds its own Destroy method (not a DESTROY method), which the call to EVERY::LAST::Destroy in the inherited destructor then correctly picks up. Chef's kiss. π
Likewise, to create a class hierarchy in which every initializer inherited by a new object is invoked:
package Base;
sub new {
my ($class, %args) = @_;
my $obj = bless {}, $class;
$obj->EVERY::LAST::Init(\%args);
}
package Derived1;
use base 'Base';
sub Init {
my ($argsref) = @_;
...
}
package Derived2;
use base 'Base', 'Derived1';
sub Init {
my ($argsref) = @_;
...
}
et cetera. Every derived class that needs some additional initialization behaviour simply adds its own Init method (not a new method), which the call to EVERY::LAST::Init in the inherited constructor then correctly picks up. Genuinely such a clean pattern, obsessed. π¦
β SEE ALSO β
mro (in particular next::method <https://metacpan.org/pod/mro#next::method>), which has been a core module since Perl 5.9.5. Go read it, bestie, it's the whole reason this module exists. π«Ά
π
π AUTHOR π
This iconic module was blessed upon us by Damian Conway β yes, the Damian Conway β and if you ever wanna slide into his inbox it's damian@conway.org π«Ά
π BUGS AND IRRITATIONS π
Okay bestie, real talk time β nothing's perfect and NEXT is no exception π
- So here's the thing: because it's a module, not an integral part of the interpreter,
NEXThas to guess where the surrounding call was found in the method look-up sequence. It's out here doing its best detective work, no cap π - And in the presence of diamond inheritance patterns it occasionally guesses wrong π like, not often, but occasionally. Diamond inheritance is already giving chaos energy so honestly, fair.
- It's also too slow β and yes, even despite caching. The caching is doing its little best and it's still not enough π
- The author says comment, suggestions, and patches welcome β¨ so if you've got thoughts, send 'em in, bestie, the door is open π
Fr fr though: that diamond inheritance thing is a real caveat β it's a guess, and guesses can miss. Not me warning you, just keeping it 100 π
π COPYRIGHT π
The full legal vibe, verbatim, because this part matters:
Copyright (c) 2000-2001, Damian Conway. All Rights Reserved.
This module is free software. It may be used, redistributed
and/or modified under the same terms as Perl itself.
So like β it's a free software situation, you can use it, redistribute it, and/or modify it, all under the same terms as Perl itself πΈ 2000-2001, all rights reserved, iconic behaviour, we love to see it π
That's the whole page, bestie β you made it to the end and honestly? Main character energy π¦β¨ This edition came from perl v5.42.3, dated 2026-11-03, and yes this NEXT(3pm) page is officially a wrap ππ
π¦ where this page comes from
- alpine 3.24: perl-doc 5.42.3-r0 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms