NAME
Class::Multi - Multiple inheritance support functions.
SYNOPSIS
A flexible inheritance traversal function.
A calling-class-relative metaphor of
can()
.A calling-class-relative metaphor of
SUPER::
.
Inheritance Traversal Function
walk_depth( \&testsub, CLASS, @avoid )
walk_width( \&testsub, CLASS, @avoid )
walk_width_up( \&testsub, CLASS, @avoid )
Executes the supplied code reference once for each superclass of the supplied derived class, until the code reference returns true.
walk_depth uses the same depth-first search order that Perl uses internally.
walk_width uses a breadth-first search order that is more appropriate for diamond inheritance situations. Thus, and also since Perl already provides methods that use depth-first, all of the other functions in this package use the breadth-first search order.
walk_width_up uses breadth-first, but starts with the base class and works its way toward the derived. This is more appropriate for a constructive purpose where the base class should initialize first, where walk_width is more appropriate for a destructive purpose where the base class should be called last.
If an @avoid list is supplied, the code reference will not be executed until all classes in that list have been seen, whichever direction it's going.
walk_width { BLOCK } $derived
Executes the { BLOCK } once each for $derived and its superclasses.
walk_width { BLOCK } $derived, $derived
Executes the { BLOCK } only for $derived's superclasses.
walk_width { BLOCK } $derived, __PACKAGE__
Executes the { BLOCK } only for classes that are inherited after the class in which the expression is found.
Multi-Inherited Method Search
other( $this, METHOD )
other
checks if the object or class $this has a method called 'METHOD', that occurs -AFTER- the calling class in the inheritance tree.
Usage and semantics are otherwise identical to UNIVERSAL::can
The calling class is inferred via caller()
.
otherpkg( $this, METHOD )
Identical to other
, except the package name is returned instead of the desired method's code reference.
otherrun( $this, METHOD, @myargs )
Identical to other
, except the function is run and its result returned instead of the desired method's code reference.
Equivalent to &{other( $this, METHOD )}( $this, @myargs );
.
Multi-Inherited Iterative Method Call
$this->EVERY::mymethod( @myargs );
=head2 $this->EVERY::MAY::mymethod( @myargs );
=head2 $this->EVERY::DOWN::mymethod( @myargs );
=head2 $this->EVERY::MAY::DOWN::mymethod( @myargs );
Syntactic sugar.
Calls every implementation of the requested method in all of $this's base classes. The method must exist at least once.
If you do not want an exception to be thrown if no method is found, call using $this->EVERY::MAY::mymethod( @myargs );
If you want the subclasses called from the top-down as normal inheritance does, but breadth-first, use either EVERY::DOWN or EVERY::MAY::DOWN.
If you do not want to provide an empty method in your base class to satisfy that, and don't like the ::MAY syntax, then you can wrap an EVERY invocation in an eval { } call. But, remember to localize @_ before you do so.
Multi-Inherited Breadth-First Chain-Up Call
$this->OTHER::mymethod( @myargs );
=head2 $this->OTHER::MAY::mymethod( @myargs );
Syntactic sugar.
Equivalent to &{other( $this, 'mymethod' )}( $this, @myargs );
.
Like SUPER::
, OTHER::
expects the requested method to exist. If it does not, an exception is thrown.
If you do not want to wrap the call in eval { }, then use OTHER::MAY.