我在使用Perl和内置函数eval
时遇到了一些麻烦。
我浏览了网页,但找不到任何答案或示例代码。
我想动态加载模块(在执行时间之前我不知道它们)
$module_name="Auth_Auth_Test";
my $ret1;
ret = eval{
"use ".$module_name;
$ret1 = $module_name."::test(".$log.")";
};
$log->debug ($@) if $@;
$log->debug ("Ret".$ret1);
回报是:
RetAuth_Auth_Test ::测试(自定义:: LOG = HASH(0x1194468))
以下方法对我有用,但我无法加载多个具有相同子程序的模块:
my $use = "use ".$module_name." qw(&test)";
$ret = eval $use;
# Debug for eval
$log->debug ($@) if $@;
$ret = test($log);
感谢您的帮助
答案 0 :(得分:4)
改为使用Module::Load。
答案 1 :(得分:2)
我强烈建议你使用Class::Load,由于穆斯的依赖性,它现在无处不在:
use Class::Load qw(:all);
my $module = 'Web::Spider::' . $module;
try_load_class($module)
or warn "unable to load '$module'";
这是一个广泛的解释,说明为什么它比Module :: Load更好(尽管后来成为Perl核心的一部分):http://blog.fox.geek.nz/2010/11/searching-design-spec-for-ultimate.html
TL; DR:
Perl 5.8功能(现在在5.10中解决)的一个怪癖是,一旦需要一个模块,只要该文件存在于磁盘上,$ INC {}将被更新以将模块名称映射到找到的文件名。这看起来并不坏,直到你看到它在其他地方被再次调用的行为方式。
Class :: Load解决了这个问题。 Module :: Load没有。
答案 2 :(得分:1)
在第一个片段中,
"use ".$module_name;
仅被评估为字符串。这是因为字符串eval
和块eval
之间存在差异。有关这些文档之间的差异,请参阅eval文档。
您可以使用以下内容:
use strict; use warnings;
my $module_name = "Auth_Auth_Test";
eval "require $module_name";
if($@) {
warn "Could not load module: $@\n";
}
my $ret = $module_name->test("params");
print "return $ret\n";
但无论如何,daxim的建议是合理的,你可能不想重新发明已经用perl分发的东西。自{5.3.4以来Module::Load处于核心地位。