use strict; use warnings; sub get_subs { my $pkg = shift; my $subs = shift || +{}; my $seen = shift || +{}; return if $seen->{ $pkg }++; my $pkg_and_dots = $pkg . '::'; my @ancestors; { no strict 'refs'; $subs->{ $_ } ||= $pkg for grep exists &{ "$pkg_and_dots$_" }, keys %{ $pkg_and_dots }; @ancestors = @{ "${pkg_and_dots}ISA" }; } @ancestors = 'UNIVERSAL' unless @ancestors || $seen->{ UNIVERSAL }; get_subs( $_, $subs, $seen ) for @ancestors; return $subs; } sub Foo::baz { 1 } @Bar::ISA = 'Foo'; my $subs = get_subs( 'Bar' ); __END__