Perl在使用前验证模块
我使用Module::Pluggable从给定目录加载模块:Perl在使用前验证模块,perl,module,Perl,Module,我使用Module::Pluggable从给定目录加载模块: for my $module ( plugins() ) { eval "use $module"; if ($@) { my $error = (split(/\n/, $@))[0]; push @rplugin_errors, $error; print STDOUT "Failed to load $module: $error\n"; } else
for my $module ( plugins() ) {
eval "use $module";
if ($@) {
my $error = (split(/\n/, $@))[0];
push @rplugin_errors, $error;
print STDOUT "Failed to load $module: $error\n";
} else {
print STDOUT "Loaded: $module\n";
my $mod = $module->new();
my $module_name = $mod->{name};
$classes{$module_name} = $mod;
}
}
此函数可以通过其他地方的重载方法调用。但是,如果我试图“使用”的模块中有一个抛出错误,那么它就不会被加载,脚本也会有点残废
我想在执行use之前验证plugins()中的每个模块。因此,理想情况下,我可以这样做:
$error = 0;
for my $module ( plugins() ) {
eval TEST $module;
if ($@) {
print STDERR "$module failed. Will not continue";
$error = 1;
last;
}
}
if ($error == 0) {
for my $module ( plugins() ) {
use $module;
}
}
改变
回到
eval "use $module";
嗯,在这里(或在您的原始代码中)导入可能没有意义,因此以下内容会更好:
eval "require $module";
我觉得你把事情复杂化了。您的代码已经包含了一个子句,用于测试
use
中的错误,并在出现错误时报告错误。(if($@)…print STDOUT“未能加载$module:$error\n”;
)根据您对ikegami回答的评论,您的目标是“如果其中一个失败,我们将停止并发送一条消息,说明由于模块错误而无法重新加载。”(是的,我知道您说过,您的目标是在加载模块之前对其进行验证。事实并非如此。您的目标是在出现错误时停止;您刚刚决定预验证是实现这一点的方法。这就是我们所说的预验证。)
您已经在检测和报告发生的任何错误…您希望在出现错误时停止…因此,当您检测到错误时,请在报告错误后停止
if ($@) {
my $error = (split(/\n/, $@))[0];
push @rplugin_errors, $error;
die "Failed to load $module: $error\n";
} else {
评估“使用模块”将在不知道模块是否正确的情况下尝试加载该模块。如果出现语法错误,它将继续加载另一个模块并排除坏模块。因此,可能有2/3的模块已加载。目标是在尝试加载之前验证所有模块。如果其中一个模块失败,我们将停止并发送消息,说明由于错误而无法重新加载模块错误。我尝试了require,但也不起作用。:/No,它不会继续尝试加载下一个,因为你调用了
last
。如果你不想影响当前进程,你必须使用不同的进程(例如系统($^X',-e',eval“use$ARGV;1”或die$@,$module)
)。你无法测试脚本/模块是否存在错误(相同的东西)将在不实际执行的情况下执行/加载(相同的东西)。因此,最好的方法是通过shell启动脚本,并使用module::foo查看是否有错误。
if ($@) {
my $error = (split(/\n/, $@))[0];
push @rplugin_errors, $error;
die "Failed to load $module: $error\n";
} else {