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

Posted

技术标签:

【中文标题】在 Perl 中处理异常的最佳方法是啥?【英文标题】:What is the best way to handle exceptions in Perl?在 Perl 中处理异常的最佳方法是什么? 【发布时间】:2011-04-29 16:59:30 【问题描述】:

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

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

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

【问题讨论】:

欺骗***.com/questions/503189/… ***.com/questions/2165161/… ***.com/questions/2439966/… ***.com/questions/1426501/… -- 我们真的需要另一篇关于 Perl 异常处理的帖子吗? 在Is Try::Tiny still recommended for exception handling in Perl 5.14 or later?查看我的回答 【参考方案1】:

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

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

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

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

这是异常处理,即使它不使用 try/catch 语法。但是,它很脆弱,并且会在大多数人没有想到的许多微妙的边缘情况下打破。 Try::Tiny 和 CPAN 上的其他异常处理模块是为了更容易正确处理而编写的。

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

【讨论】:

并且只是为了澄清原始发布者可能会或可能不会遭受的常见误解:eval BLOCKnot eval STRING 并且不会在运行时编译代码.它只是一种异常处理方法——try 有一个有趣的名字和略带滑稽的语义。 如果我们认为setjmp+longjmp 是 C 中的一种异常处理机制(无论多么粗糙),那么 shell 也有一个:trap+kill(尽管它看起来更粗糙)。 供您参考,现在 perl 中有一个完整的 try-catch 实现,模块 Nice::Try【参考方案2】:

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

通用评估模板:

my $result;

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

在实践中,这是最轻松的方式。它仍然为有趣的 $@ 行为留下了很小的空间,但没有什么让我真正关心的足够多。

【讨论】:

【参考方案3】:

正如已经提到的,您可以使用传统方式与eval,但如果您想使用更复杂的异常捕获,包括异常对象,那么我建议使用 try-catch-finally 块。 有不少 perl 模块提供它,例如 Nice::Try 和 Syntax::Keyword::Try,但 Syntax::Keyword::Try 不提供异常变量赋值或异常类捕获之类的

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

完全披露:我是Nice::Try的开发者

【讨论】:

Nice::Try 非常棒,它拥有我在 Perl 中处理异常时一直想要的一切。

以上是关于在 Perl 中处理异常的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 Perl 中获得 Epoch 毫秒的最佳方法是啥?

在 Perl 中打开和读取文件的最佳方法是啥?

在 Perl 中从数组中删除值的最佳方法是啥?

在 ASP.NET 应用程序中捕获所有异常的最佳方法是啥?

在 Perl 中将文件转换为字符串的最佳方法是啥?

从 Perl 中的文本文件读取时跳过标题的最佳方法是啥?