问题描述
我需要动态包含一个 Perl 模块,但如果可能的话,由于工作编码标准,我希望远离 eval.这有效:
I need to dynamically include a Perl module, but if possible would like to stay away from eval due to work coding standards. This works:
$module = "My::module";
eval("use $module;");
但如果可能的话,我需要一种无需 eval
的方法.所有谷歌搜索都指向 eval
方法,但没有任何其他方式.
But I need a way to do it without eval
if possible. All google searches lead to the eval
method, but none in any other way.
没有eval
可以做到吗?
推荐答案
使用 require
在运行时加载模块.将它包装在一个块(不是字符串)eval
中通常是一个好主意,以防模块无法加载.
Use require
to load modules at runtime. It often a good idea to wrap this in a block (not string) eval
in case the module can't be loaded.
eval {
require My::Module;
My::Module->import();
1;
} or do {
my $error = $@;
# Module load failed. You could recover, try loading
# an alternate module, die with $error...
# whatever's appropriate
};
使用 eval {...} 或 do {...}
语法并复制 $@
的原因是因为 $@
是一个全局变量,可以由许多不同的东西设置.您希望尽可能以原子方式获取该值,以避免出现其他原因将其设置为不同值的竞争条件.
The reason for the eval {...} or do {...}
syntax and making a copy of $@
is because $@
is a global variable that can be set by many different things. You want to grab the value as atomically as possible to avoid a race condition where something else has set it to a different value.
如果直到运行时才知道模块的名称,则必须手动在模块名称 (My::Module) 和文件名 (My/Module.pm) 之间进行转换:
If you don't know the name of the module until runtime you'll have to do the translation between module name (My::Module) and file name (My/Module.pm) manually:
my $module = 'My::Module';
eval {
(my $file = $module) =~ s|::|/|g;
require $file . '.pm';
$module->import();
1;
} or do {
my $error = $@;
# ...
};
这篇关于如何在不使用 eval 的情况下动态包含 Perl 模块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!