使用Try :: Tiny和Module :: Runtime使用try-catch时,避免使用Perl中的警告

时间:2017-06-01 12:49:52

标签: perl module runtime try-catch

我的代码目前是我的perl脚本的一部分(工作正常):

try {
        no strict 'refs';
        require_module $modules{$action_name};
        if ( &{"FFTG::${actiontype}::run"}( $action, $fs, $log ) ) {
                $log->res("SUCCESS");
        } else {
                if ( $action->{mandatory}[0] == 1 ) {
                        $log->res("FAIL, exiting.");
                        last ACTION;
                } else {
                        $log->res("FAIL, but not mandatory, continuing..");
                }
        }
}
catch {
        $log->res("MODULE NOT FOUND");
        print "no module found for action '$actiontype', unable to process this action\n";
        #warn $_;
};

但不幸的是,脚本的输出在输出中间显示了这3个错误(所有行以退出子例程开头):

starting transfer ..
no module found for action 'Transfer', unable to process this action
no module found for action 'Transfer', unable to process this action
no module found for action 'Archive', unable to process this action
Exiting subroutine via last at ./bin/fftgv2.pl line 130.
Exiting eval via last at ./bin/fftgv2.pl line 130.
Exiting subroutine via last at ./bin/fftgv2.pl line 130.
ending transfer

即使脚本完美运行,我也会发现它很脏"脏"在标准输出上显示这些错误。

有没有办法摆脱它们? (我不能使用if / then等..因为我不希望脚本以这个require_module的东西退出)。 我只是希望我的脚本在找不到模块时显示警告(确实如此),但不是这些警告

再次感谢 问候

2 个答案:

答案 0 :(得分:6)

perldoc perldiag中,我们发现这些警告位于名为"退出"的小组中。

如果您在fftgv2.pl中第130行之前使用no warnings "exiting";,则会使该块的其余部分的警告静音。

...当然,注意警告也不是最糟糕的想法。

答案 1 :(得分:4)

发出警告是因为last语句块内有trytry实际上并不是Perl语法的一部分。它不是关键字,因此,块实际上不是块。由于Try :: Tiny中的原型sub try (&;@),它只是一个被视为块的匿名子。

我们将从下往上看。

Exiting subroutine via last at ./bin/fftgv2.pl line 130. ^
Exiting eval via last at ./bin/fftgv2.pl line 130.       |
Exiting subroutine via last at ./bin/fftgv2.pl line 130. |
     

通过./bin/fftgv2.pl第130行的最后一个退出子程序。

所以第三个警告实际上来自你try的子。

try {                      # here
        no strict 'refs';
  

通过./bin/fftgv2.pl第130行的最后一个退出eval。

下一个是因为Try :: Tiny implements try via a call to evalPerl's built-in way of catching errors

这是Try :: Tiny使用的代码(突出显示评论我的):

  # failed will be true if the eval dies, because 1 will not be returned
  # from the eval body
  my $failed = not eval {              # here is 2)
    $@ = $prev_error;

    # evaluate the try block in the correct context
    if ( $wantarray ) {
      @ret = $try->();                 # and this is 3)
    } elsif ( defined $wantarray ) {
      $ret[0] = $try->();
    } else {
      $try->();
    };

    return 1; # properly set $failed to false
  };
  

通过./bin/fftgv2.pl第130行的最后一个退出子程序。

第一个警告来自Try :: Tiny本身的实际sub try

那么你能做些什么呢?如果您不想隐藏警告,则需要稍微重写代码。摆脱last块内的try,而不是通过diereturn退出。记住,毕竟这是一个功能。

然后设置一个稍后用来决定是否要跳过迭代的值。

ACTION: foreach my $action_name (@foo) {
    my $break_out;
    try {
        no strict 'refs';
        require_module $modules{$action_name};
        if ( &{"FFTG::${actiontype}::run"}( $action, $fs, $log ) ) {
            $log->res("SUCCESS");
        }
        else {
            if ( $action->{mandatory}[0] == 1 ) {
                $log->res("FAIL, exiting.");
                return $break_out = 1; # use this to exit the loop later
            }
            else {
                $log->res("FAIL, but not mandatory, continuing..");
            }
            # return is only needed if there is more code here ...
        }
        # ... or here
    }
    catch {
        $log->res("MODULE NOT FOUND");
        print "no module found for action '$actiontype', unable to process this action\n";
    };

    last ACTION if $break_out; # oops, something went wrong, break out
}