我需要动态地包含一个Perl模块,但是如果可能的话,由于工作编码标准,我希望远离eval.这有效:
$module = "My::module";
eval("use $module;");
Run Code Online (Sandbox Code Playgroud)
但是eval如果可能的话,我需要一种方法来做到这一点.所有谷歌搜索都会导致该eval方法,但没有任何其他方式.
没有可能eval吗?
Mic*_*man 48
用于require在运行时加载模块.如果eval无法加载模块,通常最好将其包装在一个块(而不是字符串)中.
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
};
Run Code Online (Sandbox Code Playgroud)
究其原因,eval {...} or do {...}语法和制作的副本$@,因为$@是可以通过许多不同的事情来设置一个全局变量.您希望尽可能原子地获取值,以避免竞争条件,其他东西已将其设置为不同的值.
如果您在运行时之前不知道模块的名称,则必须手动执行模块名称(My :: Module)和文件名(My/Module.pm)之间的转换:
my $module = 'My::Module';
eval {
(my $file = $module) =~ s|::|/|g;
require $file . '.pm';
$module->import();
1;
} or do {
my $error = $@;
# ...
};
Run Code Online (Sandbox Code Playgroud)
Dav*_*idG 16
如何使用核心模块Module :: Load
用你的例子:
use Module::Load;
my $module = "My::module";
load $module;
Run Code Online (Sandbox Code Playgroud)
"Module :: Load - 运行时需要模块和文件"
"负载消除了你是否需要知道是否需要文件或模块的需要."
如果它失败了它会死于类似"无法在@INC中找到xxx(@INC包含:......").
Dan*_*Dan 10
嗯,总是require如此
require 'My/Module.pm';
My::Module->import();
Run Code Online (Sandbox Code Playgroud)
请注意,您import在编译时而不是运行时调用可能会失去的任何效果.
编辑:这与eval方式之间的权衡是:eval允许您使用普通模块语法,如果模块名称无效(而不是仅仅找不到),则会给出更明确的错误.OTOH,eval方式(可能)更容易受到任意代码注入.
| 归档时间: |
|
| 查看次数: |
23977 次 |
| 最近记录: |