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 メソッドを介して呼び出すことができます。しかし、私が「使用」しようとしているモジュールの 1 つがエラーをスローした場合、そのモジュールはロードされておらず、スクリプトは多少不自由です。

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;
    }
}
4

2 に答える 2

0

変化する

eval TEST $module;

戻る

eval "use $module";

ここで (または元のコードで) インポートするのはおそらく意味がないので、次のようにしたほうがよいでしょう:

eval "require $module";
于 2012-09-09T00:36:05.850 に答える
0

私はあなたがこれを過度に複雑にしていると思います。コードには、 のエラーをテストし、エラーが発生しuseた場合は報告する句が既に含まれています。( if ($@)... print STDOUT "Failed to load $module: $error\n";) ikegami's answer に対するあなたのコメントによると、あなたの目標は、「失敗した場合、停止し、モジュール エラーのためにリロードを実行できなかったというメッセージを送信する」ことです。(はい、あなたの目標はモジュールをロードする前に検証することだとおっしゃいましたが、そうではありません。エラーが発生した場合に停止することが目標です。事前検証がそれを達成する方法であると判断しただけです。これがを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 に答える