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

时间:2010-10-23 21:53:56

标签: perl exception-handling error-handling eval

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

此外,Perl程序似乎对一般的异常处理有更宽松的政策。这是否有令人信服的理由?

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

3 个答案:

答案 0 :(得分:49)

Perl社区的共识似乎是Try::Tiny是进行异常处理的首选方式。您提到的“宽松政策”可能是由以下因素组合而成的:

  • Perl不是一种完全面向对象的语言。 (例如,与Java相比 你无法避免处理异常。)
  • 许多Perl开发人员的背景。 (像C 1 这样的语言和shell没有 异常机制。)
  • 人们倾向于使用Perl的任务类型。 (用于文本修改的小脚本) 报告生成,不需要进行异常处理。)
  • Perl没有(好的)内置异常机制。

请注意,最后一项意味着你会看到很多像这样的代码:

eval { something() };
if ($@) {
    warn "Oh no! [$@]\n";
}

这是异常处理,即使它不使用try / catch语法。尽管如此,它仍然很脆弱,并会打破一些大多数人都没有想到的微妙优势。尝试:: Tiny和CPAN上的其他异常处理模块的编写是为了让它更容易正确。

<子> 1。 C确实有setjmp()longjmp(),可以用于非常粗略的异常处理形式。

答案 1 :(得分:1)

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

通用评估模板:

my $result;

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

实际上,这是最简单的方法。仍然为可笑的$ @行为留出了很小的空间,但是没有什么让我真正担心的。

答案 2 :(得分:0)

如前所述,您可以对eval使用传统方式,但是如果您想使用更复杂的异常捕获(包括异常对象),那么我建议使用try-catch-finally块。 提供了很多Perl模块,例如Nice::TrySyntax::Keyword::Try,但是Syntax::Keyword::Try不提供异常变量分配或异常类捕获,如

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

完全公开:我是Nice::Try

的开发商