使用前Perl验证模块

时间:2012-09-08 23:55:18

标签: 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 {

        print STDOUT "Loaded: $module\n";
        my $mod = $module->new();
        my $module_name = $mod->{name};
        $classes{$module_name} = $mod;
    }
}

可以通过其他地方的重载方法调用此函数。但是,如果我试图“使用”的其中一个模块抛出一个错误,它就没有加载,而且脚本有点瘫痪。

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

2 个答案:

答案 0 :(得分:0)

更改

eval TEST $module;

回到

eval "use $module";

好吧,导入可能在这里(或在原始代码中)没有意义,所以以下会更好:

eval "require $module";

答案 1 :(得分:0)

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

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

if ($@) {
    my $error = (split(/\n/, $@))[0];
    push @rplugin_errors, $error;
    die "Failed to load $module: $error\n";
} else {