我可以从任何Perl模块动态获取函数或函数名列表吗?

时间:2010-12-09 23:49:16

标签: perl perl-module

我想从我的系统上可用的任意Perl模块动态获取函数名称(作为字符串)或函数引用的列表。这将包括可能具有或不具有的模块,例如其命名空间中的全局@EXPORT_OK数组。这样的壮举有可能吗?如果是这样的话怎么把它拉下来?

修改:从阅读perlmod开始,我看到%Some::Module::充当Some::Module的符号表。这是正确的地方吗?如果是这样,我怎样才能将表格缩小到Some::Module中的函数名称?

3 个答案:

答案 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