Reputation: 12791
I would like to dynamically get a list of either function names (as strings) or function references from any arbitrary Perl module available on my system. This would include modules that may or may not have, e.g., a global @EXPORT_OK
array in its namespace. Is such a feat possible? How does one pull it off if so?
Edit: From reading perlmod, I see that %Some::Module::
serves as a symbol table for Some::Module
. Is this the correct place to be looking? If so, how can I whittle the table down to just the function names in Some::Module
?
Upvotes: 9
Views: 5751
Reputation: 3649
I'm using Perl 5.20. This works on my machine:
use strict;
package foo;
our $some_var;
sub func1 { return 'func1'}
sub func2 { return 'func2'}
package main;
sub callable {
my ($x) = @_;
return defined(&$x);
}
while (my ($k, $v) = each(%foo::)) {
if (callable($v)) {
print("$k\n");
}
}
# output:
# func1
# func2
Upvotes: 1
Reputation: 53966
You may find this simple script handy:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
# dump of object's symbol table:
foreach my $className (@ARGV)
{
print "symbols in $className:";
eval "require $className";
die "Can't load $className: $@" if $@;
no strict 'refs';
print Dumper(\%{"main::${className}::"});
}
But, if you're doing this in production code, I'd use Package::Stash instead:
my @subs_in_foo = Package::Stash->new('Foo')->list_all_symbols('CODE');
Upvotes: 8
Reputation: 129363
You're on the right track. To wittle down the full symbol table to just the subs, something like this can be done (Hat tip "Mastering Perl", ch 8, for main package version of this):
use strict; # need to turn off refs when needed
package X;
sub x {1;};
sub y {1;};
our $y = 1;
our $z = 2;
package main;
foreach my $entry ( keys %X:: ) {
no strict 'refs';
if (defined &{"X::$entry"}) {
print "sub $entry is defined\n" ;
}
}
# OUTPUT
sub y is defined
sub x is defined
Upvotes: 9