Jarkko Hietaniemi > perl-5.7.2 > NEXT

Download:
perl-5.7.2.tar.gz

Dependencies

Annotate this POD

Source   Latest Release: perl-5.8.1

NAME ^

NEXT.pm - Provide a pseudo-class NEXT that allows method redispatch

SYNOPSIS ^

        use NEXT;

        package A;
        sub A::method   { print "$_[0]: A method\n";   $_[0]->NEXT::method() }
        sub A::DESTROY  { print "$_[0]: A dtor\n";     $_[0]->NEXT::DESTROY() }

        package B;
        use base qw( A );
        sub B::AUTOLOAD { print "$_[0]: B AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
        sub B::DESTROY  { print "$_[0]: B dtor\n";     $_[0]->NEXT::DESTROY() }

        package C;
        sub C::method   { print "$_[0]: C method\n";   $_[0]->NEXT::method() }
        sub C::AUTOLOAD { print "$_[0]: C AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
        sub C::DESTROY  { print "$_[0]: C dtor\n";     $_[0]->NEXT::DESTROY() }

        package D;
        use base qw( B C );
        sub D::method   { print "$_[0]: D method\n";   $_[0]->NEXT::method() }
        sub D::AUTOLOAD { print "$_[0]: D AUTOLOAD\n"; $_[0]->NEXT::AUTOLOAD() }
        sub D::DESTROY  { print "$_[0]: D dtor\n";     $_[0]->NEXT::DESTROY() }

        package main;

        my $obj = bless {}, "D";

        $obj->method();         # Calls D::method, A::method, C::method
        $obj->missing_method(); # Calls D::AUTOLOAD, B::AUTOLOAD, C::AUTOLOAD

        # Clean-up calls D::DESTROY, B::DESTROY, A::DESTROY, C::DESTROY

DESCRIPTION ^

NEXT.pm adds a pseudoclass named NEXT to any program that uses it. If a method m calls $self-NEXT::m()>, the call to m is redispatched as if the calling method had not originally been found.

In other words, a call to $self-NEXT::m()> resumes the depth-first, left-to-right search of parent classes that resulted in the original call to m.

A typical use would be in the destructors of a class hierarchy, as illustrated in the synopsis above. Each class in the hierarchy has a DESTROY method that performs some class-specific action and then redispatches the call up the hierarchy. As a result, when an object of class D is destroyed, the destructors of all its parent classes are called (in depth-first, left-to-right order).

Another typical use of redispatch would be in AUTOLOAD'ed methods. If such a method determined that it was not able to handle a particular call, it might choose to redispatch that call, in the hope that some other AUTOLOAD (above it, or to its left) might do better.

Note that it is a fatal error for any method (including AUTOLOAD) to attempt to redispatch any method except itself. For example:

        sub D::oops { print "oops!\n"; $_[0]->NEXT::other_method() }

AUTHOR ^

Damian Conway (damian@conway.org)

BUGS AND IRRITATIONS ^

Because it's a module, not an integral part of the interpreter, NEXT.pm has to guess where the surrounding call was found in the method look-up sequence. In the presence of diamond inheritance patterns it occasionally guesses wrong.

It's also too slow (despite caching).

Comment, suggestions, and patches welcome.

COPYRIGHT ^

 Copyright (c) 2000, Damian Conway. All Rights Reserved.
 This module is free software. It may be used, redistributed
and/or modified under the terms of the Perl Artistic License
     (see http://www.perl.com/perl/misc/Artistic.html)
syntax highlighting: