Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to discover all subroutines a Perl module has?

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.

like image 208
Robert P Avatar asked Mar 03 '09 17:03

Robert P


3 Answers

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\::"}
}
like image 116
Leon Timmermans Avatar answered Oct 22 '22 12:10

Leon Timmermans


Class::Inspector:

Class::Inspector allows you to get information about a loaded class. Most or all of this information can be found in other ways, but they aren't always very friendly, and usually involve a relatively high level of Perl wizardry, or strange and unusual looking code. Class::Inspector attempts to provide an easier, more friendly interface to this information...

like image 38
jrockway Avatar answered Oct 22 '22 11:10

jrockway


Have a look at this: Class::Sniff

The interface is rather ad-hoc at the moment and is likely to change. After creating a new instance, calling the report method is your best option. You can then visually examine it to look for potential problems:

my $sniff = Class::Sniff->new({class => 'Some::Class'});
print $sniff->report;

This module attempts to help programmers find 'code smells' in the object-oriented code. If it reports something, it does not mean that your code is wrong. It just means that you might want to look at your code a little bit more closely to see if you have any problems.

At the present time, we assume Perl's default left-most, depth-first search order. We may alter this in the future (and there's a work-around with the paths method. More on this later)...

like image 9
nxadm Avatar answered Oct 22 '22 11:10

nxadm