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

enn*_*ler 28 error-handling perl exception-handling eval

我注意到Exception.pm和Error.pm似乎没有在Perl社区中广泛使用.这是因为eval异常处理的占地面积很大吗?

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

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

Mic*_*man 51

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

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

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

eval { something() };
if ($@) {
    warn "Oh no! [$@]\n";
}
Run Code Online (Sandbox Code Playgroud)

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

1.Ç确实有setjmp()longjmp(),其可用于异常处理的非常粗的形式.

  • 并且只是为了澄清原始海报可能会或可能不会遭受的常见误解:"eval BLOCK"不是*`eval STRING`并且不会在运行时编译代码.它只是一个异常处理方法 - 带有趣名字和轻微滑稽语义的`try`. (15认同)

小智 8

切勿按原样测试 $@,因为它是一个全局变量,因此即使测试本身也可以更改它。

通用评估模板:

my $result;

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

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