我想从我的系统上可用的任意Perl模块动态获取函数名称(作为字符串)或函数引用的列表。这将包括可能具有或不具有的模块,例如其命名空间中的全局@EXPORT_OK
数组。这样的壮举有可能吗?如果是这样的话怎么把它拉下来?
修改:从阅读perlmod开始,我看到%Some::Module::
充当Some::Module
的符号表。这是正确的地方吗?如果是这样,我怎样才能将表格缩小到Some::Module
中的函数名称?
答案 0 :(得分:7)
您可以找到这个简单的脚本:
#!/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}::"});
}
但是,如果您在生产代码中执行此操作,我会使用Package::Stash代替:
my @subs_in_foo = Package::Stash->new('Foo')->list_all_symbols('CODE');
答案 1 :(得分:7)
你走在正确的轨道上。要将整个符号表减少到只有sub,可以这样做(Hat tip“Mastering Perl”,第8章,主要包版本):
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
答案 2 :(得分:0)
我正在使用Perl 5.20。这适用于我的机器:
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