views:

793

answers:

3

What's the best way to programatically discover all of the subroutines a perl module has? This could be a module, a class (no @EXPORT), or anything in-between.

Edit: All of the methods below look like they will work. I'd probably use the Class::Sniff or Class::Inspector in production. However, Leon's answer is marked as 'accepted' since it answers the question as posed, even though no strict 'refs' has to be used. :-) Class::Sniff may be a good choice as it progresses; it looks like a lot of thought has gone into it.

+12  A: 
sub list_module {
    my $module = shift;
    no strict 'refs';
    return grep { defined &{"$module\::$_"} } keys %{"$module\::"}
}

ETA: if you want to filter out imported subroutines, you can do this

use B qw/svref_2object/;

sub in_package {
    my ($coderef, $package) = @_;
    my $cv = svref_2object($coderef);
    return if not $cv->isa('B::CV') or $cv->GV->isa('B::SPECIAL');
    return $cv->GV->STASH->NAME eq $package;
}

sub list_module {
    my $module = shift;
    no strict 'refs';
    return grep { defined &{"$module\::$_"} and in_package(\&{*$_}, $module) } keys %{"$module\::"}
}
Leon Timmermans
This will also list subroutines that the module imported from other modules.
innaM
That would be problematic.
Robert P
On second thought, it may also be important, depending on the application.
Robert P
True, but there is no easy way to get around that, I think. namespace::clean is the answer to such problems ;-)
Leon Timmermans
You'd want exists instead of defined to pick up autoloaded subs.
ysth
ysth
5.10 uses the new constsubs, so it's logical they aren't filtered out. Not sure how to filter those out though...
Leon Timmermans
+8  A: 

Have a look at this: http://search.cpan.org/dist/Class-Sniff/lib/Class/Sniff.pm

Looks interesting, but fairly new. I'd be hesitant to use it in a production environment.
Robert P
What reasons could you possibly have to get a list of methods in a production environment?
innaM
I'm interested in prototyping out a Test::Class like tool. Developing prototypes off other untested code can lead to big headaches. :)
Robert P
Good point. I just hope you are not going to test on the production servers.
innaM
xdg
@RobertP You're ready to copy a snippet of code off a web page but balking at a module with documentation and tests? Face your CPAN-phobia.
Schwern
Not CPAN phobia, just a natural instinct to shy at "version 0.08". :)
Robert P
+5  A: 

Class::Inspector.

jrockway
Very interesting, I'll take a look at it.
Robert P