在 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 BLOCK
是 not 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 中处理异常的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章