in reply to Reflecting on Object
As a first approximation (with all the caveats already mentioned by halley):
This only tells you the subs in Some::Module's symbol table at the time. For one thing it does not differentiate between instance methods and class methods. Neither does it differentiate betweeen "methods" (i.e. functions that are expected to be called through a -> notation) and regular functions. In fact, if Some::Module imported some random function (e.g. croak or floor), it will be listed in @my_subs. It also doesn't show subs stored in lexicals.{ no strict 'refs'; @my_subs = grep exists &{ 'Some::Module::' . $_ }, keys %Some::Modul +e::; }
Try it with a module you know (or think you know) and see what you get.
Update: Also, the above does not take into account inheritance. You'd need to adapt it to travel up @ISA's to get inherited methods.
Here's a stab at it:
Now $subs points to a hash whose contents are: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__
'VERSION' => 'UNIVERSAL' 'baz' => 'Foo' 'can' => 'UNIVERSAL' 'isa' => 'UNIVERSAL'
the lowliest monk
|
|---|