Perl在使用前验证模块

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

我使用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 {

        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 {