2010-05-19 75 views
14

我学习的Perl,并在很多我看到错误的例子是这样Perl中错误处理的最佳实践是什么?

open FILE, "file.txt" or die $!; 

的处理是在脚本中间die真正处理错误的最好方法?

+6

有关perl异常的讨论,请参见[有关perl中异常的细节?](http://stackoverflow.com/questions/2165161/whats-broken-about-exceptions-in-perl),[您是否使用Perl程序中的异常类?为什么或为什么?](http://stackoverflow.com/questions/2439966/do-you-use-an-exception-class-in-your-perl-programs-why-or-why-not)和[在Perl中面向对象的异常处理 - 是否值得?](http://stackoverflow.com/questions/503189/object-oriented-exception-handling-in-perl-is-it-worth-it) – Ether 2010-05-19 22:14:47

回答

21

是否die在脚本中间是否合适取决于您在做什么。如果只有几十行,那很好。一个有几百行的小工具,然后考虑承认(见下文)。如果它是一个大型的面向对象的系统,有很多类和相互关联的代码,那么可能有一个异常对象会更好。

忏悔在Carp包:
常导致模具中的错误是不是对死亡的报告线。 用坦白替换模具(参见Carp软件包)会给堆栈追踪(我们如何到达这条线),这极大地帮助调试。

为了处理来自Perl内建函数的异常,我喜欢使用autodie。它从open和其他系统调用中捕获故障,并且会为您抛出异常,而不必执行or die位。这些例外情况可以通过eval { }或更好的方式使用Try::Tiny来捕获。

+4

用于提示'autodie'。 – 2010-05-19 20:57:45

+1

我一直以为他们应该称之为'autoOrDie' :) – friedo 2010-05-20 02:40:40

+0

@friedo它看起来很像'authorDie' :) – dolmen 2014-06-04 16:01:50

3

更现代的方法是使用鲤鱼标准库。

use Carp; 
my $fh; 
open $fh, '<', "file.txt" or confess($!); 

它的主要优点是它给死亡的堆栈跟踪。

+0

,除非你设置了一些其他的鲤鱼东西,否则cro鱼不会给出堆栈跟踪。 – 2010-05-19 20:58:17

+0

@brian:whoop,固定。 – 2010-05-19 20:59:24

+1

谢谢!我不知道鲤鱼......但是从什么时候开始鲤鱼呱呱叫? – SystematicFrank 2010-05-19 20:59:41

0

我使用模具,但我把它包装的eval块在错误处理控制:

my $status = eval 
{ 
    # Some code... 
}; 

如果 'EVAL' 失败:

  1. $status将是不确定的。
  2. [email protected]将被设置的任何错误消息被产生的(或 一个die的内容)

如果“EVAL”成功:

  1. $status将是最后一个返回值块。
  2. [email protected]将被设置为''。
+5

'eval {}'有很多问题需要隐晦的解决方法。改用Try :: Tiny。它将所有有害的样板包裹在干净,易于使用的包装中。 – daotoad 2010-05-19 21:54:24

+1

eval {}'有很多问题需要隐晦的解决方法...如果您关心识别错误。如果你打算采取同样的行动,不管其原因如何,一个简单的块'eval'工作正常。但是,是的:在所有其他情况下使用'Try :: Tiny'。 – 2010-05-20 09:40:36

+0

下次我编写一些Perl时,我会尝试一下。我使用这种方式来伪造try-catch(通过在eval块之后添加$ @的检查。)感谢提示。 – 2010-05-20 14:23:31

12

由于我几乎在任何地方都使用Log::Log4perl,所以我用$logger->logdie代替die。如果您想对您的例外有更多的控制权,请考虑Exception::Class

最好用Try::Tiny(请参阅它的文档为什么)了解您的例外情况。

6

除非你有一个更具体的想法,然后是的当意想不到的事情发生时,你想死。

  • 死亡对未能打开一个文件,并给予文件名是不是系统告诉你它无法读取或写入到一个匿名未定义的更好。

  • 如果你正在谈论一个“脚本”,一般来说你正在谈论一段非常简单的代码。不需要协调的层(通常不)。在一个Perl 模块中,有一个随之而来的想法是你不拥有执行环境,所以无论是主软件还是关心它,并且它在eval中捕获事物,或者它并不真正关心和死亡就没有问题。然而,你应该尝试一个更健壮的模块作为模块,并传回undefs或其他东西。

  • 你可以在eval块中捕获任何死亡(或cro)声)。你可以在那里做更具体的处理。

  • 但是如果你想检查$!那么写的代码,你会有一个更具体的决议。

  • 看看使用strict的近似通用标准。这是死于可疑语法的代码,而不是让你继续。

所以我觉得总体思路是:是,DIE,除非你有事情应该如何处理一个更好的主意。如果你有足够的先见之明,你可以原谅你不会死的一两次,因为你知道你不需要。

相关问题