在Perl中处理异常的最佳方法是什么?

在Perl中处理异常的最佳方法是什么?,perl,exception-handling,error-handling,eval,Perl,Exception Handling,Error Handling,Eval,我注意到Exception.pm和Error.pm在Perl社区中似乎没有被广泛使用。这是因为异常处理的eval占用了大量空间吗 另外,对于异常处理,Perl程序通常有一个更宽松的策略。有没有令人信服的理由 无论如何,Perl中处理异常的最佳方法是什么?Perl社区的共识似乎是,这是处理异常的首选方法。您提到的“宽大政策”可能是由以下因素造成的: Perl不是一种完全面向对象的语言。(例如,与Java相比 您无法避免处理异常。) 许多Perl开发人员的背景。(像C1和shell这样的语言没有

我注意到Exception.pm和Error.pm在Perl社区中似乎没有被广泛使用。这是因为异常处理的
eval
占用了大量空间吗

另外,对于异常处理,Perl程序通常有一个更宽松的策略。有没有令人信服的理由


无论如何,Perl中处理异常的最佳方法是什么?

Perl社区的共识似乎是,这是处理异常的首选方法。您提到的“宽大政策”可能是由以下因素造成的:

  • Perl不是一种完全面向对象的语言。(例如,与Java相比 您无法避免处理异常。)
  • 许多Perl开发人员的背景。(像C1和shell这样的语言没有 异常机制。)
  • 人们倾向于使用Perl执行的任务类型。(用于文本咀嚼和 不需要异常处理的报告生成。)
  • Perl没有(好的)内置异常机制
请注意,最后一项意味着您将看到很多这样的代码:

eval { something() };
if ($@) {
    warn "Oh no! [$@]\n";
}
这是异常处理,即使它不使用try/catch语法。虽然它很脆弱,但它会在许多微妙的边缘情况下断裂,而这些情况大多数人都没有想到。Try::Tiny和CPAN上的其他异常处理模块的编写目的是使其更容易正确


一,。C确实有
setjmp()
longjmp()
,它们可以用于非常粗糙的异常处理形式。

永远不要按原样测试$@因为它是一个全局变量,所以即使测试本身也可以更改它

通用评估模板:

my $result;

eval {
    $result= something();
    # ...
    1;  # ok
} or do {
    my $eval_error= $@ || "error";
    # ...
    die $eval_error;
};  # needs a semicolon

实际上,这是最轻松的方式。它仍然为有趣的$@行为留下了一个很小的空间,但没有什么真正让我感到足够的关注。

正如前面提到的,您可以使用传统的方法,但是如果您想使用更复杂的异常捕获,包括异常对象,那么我建议使用try-catch-finally块。 有相当多的perl模块提供了它,如和,但不提供异常变量分配或异常类捕获

  try
  {
    # something
  }
  catch( Exception $e )
  {
    # catch this in $e
  }

充分披露:我是

dupe of的开发者——我们真的需要另一篇关于Perl异常处理的帖子吗?请参阅中的我的答案,只是为了澄清一个常见的误解,这一误解可能是原始帖子中的:
eval BLOCK
不是
eval STRING
,并且不会在运行时编译代码。这只是一个异常处理方法--<代码>尝试< /COD>一个有趣的名字和稍微有趣的语义学。如果我们考虑“代码> SETJMP LojMPP < /Cord> C中的一个异常处理机制(那么粗略),那么shell也有一个:<代码>陷阱>代码> +>代码>杀灭< /代码>(尽管它看起来更粗糙)。