以编程方式发现perl模块的所有子程序的最佳方法是什么?这可以是一个模块,一个类(没有@EXPORT),或者介于两者之间的任何东西。
编辑:以下所有方法看起来都有效。我可能在生产中使用Class :: Sniff或Class :: Inspector。然而,Leon的回答被标记为“已接受”,因为它回答了所提出的问题,即使必须使用no strict 'refs'
。 :-) Class :: Sniff可能是一个很好的选择,因为它的进展;看起来已经有很多想法了。
答案 0 :(得分:22)
sub list_module {
my $module = shift;
no strict 'refs';
return grep { defined &{"$module\::$_"} } keys %{"$module\::"}
}
ETA:如果你想过滤掉导入的子程序,你可以这样做
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\::"}
}
答案 1 :(得分:12)
Class :: Inspector允许您获取有关已加载类的信息。大多数或所有这些信息都可以通过其他方式找到,但它们并不总是非常友好,并且通常涉及相对较高级别的Perl魔法,或者奇怪且不寻常的代码。 Class :: Inspector试图为这些信息提供一个更简单,更友好的界面...
答案 2 :(得分:9)
看看这个: Class::Sniff
此时界面非常特别,可能会发生变化。创建新实例后,调用报表方法是最佳选择。然后,您可以直观地检查它以查找潜在的问题:
my $sniff = Class::Sniff->new({class => 'Some::Class'}); print $sniff->report;
该模块试图帮助程序员在面向对象的代码中找到“代码味道”。如果它报告某些内容,则并不意味着您的代码是错误的。这只是意味着你可能想要更仔细地查看你的代码,看看你是否有任何问题。
目前,我们假设Perl默认最左侧,深度优先搜索顺序。我们将来可能会对此进行更改(并且会对路径方法进行解决。稍后会详细介绍)...