vi(ing has asked for the wisdom of the Perl Monks concerning the following question:

#!/usr/bin/perl use strict; use warnings; use NEXT; { package A; sub method { print "$_[0]: A method\n"; $_[0]->NEXT::method() +}; sub DESTROY { print "$_[0]: A dtor\n"; $_[0]->NEXT::DESTROY() +}; } { package B; use base qw( A ); sub AUTOLOAD { print "$_[0]: B AUTOLOAD\n"; $_[0]->NEXT::AUTOL +OAD() }; sub DESTROY { print "$_[0]: B dtor\n"; $_[0]->NEXT::DESTROY() +}; } { package C; sub method { print "$_[0]: C method\n"; $_[0]->NEXT::method() +}; sub AUTOLOAD { print "$_[0]: C AUTOLOAD\n"; $_[0]->NEXT::AUTOL +OAD() }; sub DESTROY { print "$_[0]: C dtor\n"; $_[0]->NEXT::DESTROY() +}; } { package D; use base qw( B C ); sub method { print "$_[0]: D method\n"; $_[0]->NEXT::method() +}; sub AUTOLOAD { print "$_[0]: D AUTOLOAD\n"; $_[0]->NEXT::AUTOL +OAD() }; sub DESTROY { print "$_[0]: D dtor\n"; $_[0]->NEXT::DESTROY() +}; } package main; my $obj = bless {}, "B"; $obj->method();
Result is :
B AUTOLOAD
D dtor
#!/usr/bin/perl use strict; use warnings; use NEXT; { package A; sub method { print "$_[0]: A method\n"; $_[0]->NEXT::method() +}; sub DESTROY { print "$_[0]: A dtor\n"; $_[0]->NEXT::DESTROY() +}; } { package C; sub method { print "$_[0]: C method\n"; $_[0]->NEXT::method() +}; sub AUTOLOAD { print "$_[0]: C AUTOLOAD\n"; $_[0]->NEXT::AUTOL +OAD() }; sub DESTROY { print "$_[0]: C dtor\n"; $_[0]->NEXT::DESTROY() +}; } { package D; use base qw( B C ); sub method { print "$_[0]: D method\n"; $_[0]->NEXT::method() +}; sub AUTOLOAD { print "$_[0]: D AUTOLOAD\n"; $_[0]->NEXT::AUTOL +OAD() }; sub DESTROY { print "$_[0]: D dtor\n"; $_[0]->NEXT::DESTROY() +}; } { package B; use base qw( A ); sub AUTOLOAD { print "$_[0]: B AUTOLOAD\n"; $_[0]->NEXT::AUTOL +OAD() }; sub DESTROY { print "$_[0]: B dtor\n"; $_[0]->NEXT::DESTROY() +}; } package main; my $obj = bless {}, "B"; $obj->method();
Result is:
A method
B dtor
A dtor

Why?

Replies are listed 'Best First'.
Re: use NEXT;
by stvn (Monsignor) on Apr 05, 2008 at 19:42 UTC

    NEXT is generally considered evil (ask any of the Catalyst core devs, they will tell you horror stories to make your skin crawl). If you are doing heavy MI (multiple inheritance) you should probably look into Class::C3, it brings sanity to MI in a very nice way and is much faster then NEXT (especially if you use Class::C3::XS).

    -stvn
Re: use NEXT;
by ikegami (Patriarch) on Apr 05, 2008 at 20:05 UTC

    It's related to you loading B unintentially. Renaming A, B, C & D to PkgA, PkgB, PkgC & PkgD in the first snippet causes it to output the same thing as the second snippet.

    Update: Forgot to mention:

    The use of base is discouraged. The usual problem is that it's silent when it fails to load a module (leading to weird error messages). This time, the problem was that it's silent when successfully loading a module (leading to weird behaviour).

      <quote>The use of base is discouraged. </quote>

      By whom is it discouraged?

        If you want to have a module that does what base.pm claims, look at my module, parent.pm. It was originally written as a replacement for base.pm, but the Backwards Compatibility Police prevented the outright replacement of base.pm. Hence, parent.pm. I have a (German) talk on the problems of base.pm, which I'll maybe give at the next YAPC::Europe in Copenhagen.

        By the documentation for the module itself, in a forthcoming release. The use of to-be-core parent is encouraged.
Re: use NEXT;
by Anonymous Monk on Apr 20, 2008 at 12:33 UTC
    Hi, I thought you would mean Use Next (German), a German Usenet Provider considered to be too expensive. So I think I am wrong here!?
      UseNeXT is the best Usenet Provider !!! :)