使用try::Tiny和Module::Runtime使用try-catch时避免在Perl中出现警告

使用try::Tiny和Module::Runtime使用try-catch时避免在Perl中出现警告,perl,module,runtime,try-catch,Perl,Module,Runtime,Try Catch,我目前在perl脚本的一部分中有这段代码(工作正常): 但是不幸的是,脚本的输出在输出中间显示了这3个错误(所有的行都是从退出子程序< /强>开始): 即使脚本工作正常,我发现在标准输出上显示这些错误也是“肮脏的” 有办法摆脱它们吗? (我不能使用if/then等,因为我不希望脚本与此require_模块一起退出)。 我只想让脚本在找不到模块时显示一个警报(它找到了),而不是这些警告 再次感谢 关于在中,我们发现这些警告位于名为“退出”的组中 如果使用了无警告“退出”就在fftgv2.pl中第1

我目前在perl脚本的一部分中有这段代码(工作正常):

但是不幸的是,脚本的输出在输出中间显示了这3个错误(所有的行都是从<强>退出子程序< /强>开始):

即使脚本工作正常,我发现在标准输出上显示这些错误也是“肮脏的”

有办法摆脱它们吗? (我不能使用if/then等,因为我不希望脚本与此require_模块一起退出)。 我只想让脚本在找不到模块时显示一个警报(它找到了),而不是这些警告

再次感谢 关于

在中,我们发现这些警告位于名为“退出”的组中

如果使用了
无警告“退出”就在fftgv2.pl中第130行之前,您将使该块其余部分的警告静音


。。。当然,注意警告也不是最糟糕的主意。

发出警告是因为在
try
语句块中有
last
try
实际上不是Perl语法的一部分。它不是关键字,因此,块不是真正的块。因为try::Tiny中的原型
sub-try(&;@)
,它只是一个被当作块处理的匿名sub

我们将从下往上看

通过last at./bin/fftgv2.pl第130行退出子例程

因此,第三个警告实际上来自您的
try
子系统

try {                      # here
        no strict 'refs';
通过last at./bin/fftgv2.pl第130行退出eval

下一个原因是Try::Tiny

这是Try::Tiny使用的代码(突出显示的注释):

通过last at./bin/fftgv2.pl第130行退出子例程

第一个警告来自try::Tiny本身中的实际
子try


那么你能做些什么呢?如果您不想仅仅隐藏警告,那么需要稍微重写代码。去掉
try
块中的
最后一个
,或者通过
模具退出,或者简单地
返回
。记住,它毕竟是一个函数

然后设置一个值,稍后用于决定是否要跳过迭代

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
}

您确定它们不是来自您编写的代码,还是您自己的代码库中的代码?我想它们是来自某些东西。但是我还没有完全理解这一点。很抱歉,simbabque,代码很长,我没有故意粘贴所有内容,但我有一个标签,名为ACTION:在一个更高的循环上(此处未显示),谢谢你,tjd的解决方案解决了这个问题,即使隐藏警告不是一个好主意,我也可以隐藏“我想要的警告”:)哦,我现在看到了。很抱歉对last的调用位于try块中,try块不是块,而是匿名sub。这就是它抱怨的原因。您需要设置一个范围在try之外的变量,并使用它在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. |
try {                      # here
        no strict 'refs';
  # 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
  };
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
}