in reply to What package is the method in?

I didn't find any modules that provided that functionality (although I didn't look very hard), but it's easy to code:

use mro; sub find_implementor { my ($class, $method) = @_; for my $parent (@{ mro::get_linear_isa($class) }) { no strict 'refs'; return $parent if exists( &{"${parent}::$method"} ); } return 'UNIVERSAL' if UNIVERSAL->can($method); return find_implementor($class, 'AUTOLOAD') if $method ne 'AUTOLOAD' && $class->can($method); return undef; }
use strict; use warnings; {package Foo; sub m1; sub m2 {} our @a; } {package Bar; our @ISA = 'Foo'; } print(find_implementor('Bar', 'm1' ) // "[undef]", "\n"); # Foo print(find_implementor('Bar', 'm2' ) // "[undef]", "\n"); # Foo print(find_implementor('Bar', 'a' ) // "[undef]", "\n"); # [undef] print(find_implementor('Bar', 'isa') // "[undef]", "\n"); # UNIVERSAL

Update: Added support for AUTOLOAD. Fixed strict error in test.
Update: Fixed AUTOLOAD.

Replies are listed 'Best First'.
Re^2: What package is the method in?
by Anonymous Monk on May 15, 2010 at 11:58 UTC
    This doesn't look right. Perl's dispatcher will search through the entire @INC plus UNIVERSAL for the method. If it can't find it, it repeats the search from the beginning for AUTOLOAD. So if the first parent defines AUTOLOAD and the second parent defines sub foo {}, the second parent's foo {} is called before the first parent's AUTOLOAD.
      Thanks, Fixed. Since one should override can when one has an AUTOLOAD, I only search for AUTOLOAD if the class reports it has such a method.