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.
|