在没有外部库的情况下尝试在 Perl 中 Catch

问题描述 投票:0回答:3

我正在从 Java 代码生成 Perl 代码,并尝试模拟

try
catch
机制。 我无法使用外部库。我发现了两种可能的方法来模拟这种行为:

第一个:

eval {
     ...
};
if ($@) {
     errorHandler($@);
}

第二:

unless(.....){
    // handle the error
}

我对 Perl 的了解很少。据我了解,第一个解决方案使我能够执行多个命令,而第二个解决方案使我只能执行一个命令。 但是,我也看到不建议使用 eval。

“正确”的做法是什么?

perl error-handling try-catch
3个回答
7
投票

你的第二个片段根本没有捕获异常,所以它不是一个选项。您在 core[1] 中的选项是:

  1.  my $rv;
     if (!eval { $rv = f(); 1 } ) {
        warn($@);
     }
    
  2.  my $rv = eval { f() };
     if ($@) {
        warn($@);
     }
    

    (第二个版本的)缺点:在 5.14 之前,如果对象析构函数破坏了

    $@
    ,则异常可能会被忽视。

核心之外,

  1. 尝试捕捉

    use TryCatch;
    
    try {
       f();
    } catch($e) {
       warn($e);
    }
    
  2. 不错::尝试

    use Nice::Try;
    
    try {
       f();
    } catch($e) {
       warn($e);
    }
    
  3. 尝试::小

    use Try::Tiny;
    
    my $rv = try {
       f();
    } catch {
       warn($_);
    };
    

    (Try::Tiny 版本的)缺点:这些块是伪装的子块,因此您无法在其中使用

    return

可能还有其他人。


  1. 一个愚蠢的要求。许多有用的工具在核心中不可用,并且核心中可用的模块不一定是最好的,甚至不是推荐的。

1
投票

Eval 是我们在工作中使用的典型方法,但是

Try::Tiny
是一个相当小的模块,并且使用起来很简单。但是,因为您不想使用任何外部模块。

unless
实际上并不是一个可行的选择,因为它不会捕获
die
croak
的代码片段。所以你只剩下
eval

# named special variables
use English qw(-no_match_vars); 

eval {
  # try
};
if ($EVAL_ERROR) {
  # catch
}

0
投票

此处答案的更新:自 perl-v5.34 起,现在对

try-catch
块提供了核心实验支持,并且自 2022 年 5 月 28 日版本 5.36 起,对
finally 提供了支持
块。然而,目前还不支持异常类

因此,您无需任何外部模块即可做到:

use v5.36;
use strict;
use warnings;
use feature 'try';
try {
    attempt();
    print "Success\n";
}
catch ($e) {
    print "Failure\n";
}
finally {
    print "This happens regardless\n";
}
© www.soinside.com 2019 - 2024. All rights reserved.