0

我正在使用 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;
    }
}

可以通过其他地方的 reload 方法调用此函数。但是,如果我试图“使用”的模块之一引发错误,则它不会被加载并且脚本有些瘫痪。

我想在执行使用之前验证 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;
    }
}
4

2 回答 2

0

我认为你过于复杂了。您的代码已经包含一个子句,用于测试 中的错误use并在发生错误时报告错误。( if ($@)... print STDOUT "Failed to load $module: $error\n";) 根据您对 ikegami 答案的评论,您的目标是“如果失败,我们会暂停并发送一条消息,说明由于模块错误而无法进行重新加载。” (是的,我知道您说过您的目标是在加载模块之前对其进行验证。事实并非如此。您的目标是在出现错误时停止;您刚刚决定预验证是实现此目的的方法。这就是我们所说的XY 问题。)

您已经在检测并报告发生的任何错误...您希望在出现错误时停止...因此,当您检测到错误时,请在报告后停止。

if ($@) {
    my $error = (split(/\n/, $@))[0];
    push @rplugin_errors, $error;
    die "Failed to load $module: $error\n";
} else {
于 2012-09-09T21:11:39.753 回答
0

改变

eval TEST $module;

回到

eval "use $module";

好吧,在此处(或在您的原始代码中)导入可能没有意义,因此以下内容会更好:

eval "require $module";
于 2012-09-09T00:36:05.850 回答