Perl模块是否应该引发异常(die / croak)?

时间:2010-08-22 15:39:01

标签: perl module exception

编写Perl模块时,在模块中使用croak / die是一个好习惯吗?

毕竟,如果调用者没有使用eval块,模块可能会使调用它的程序崩溃。

这些案例的最佳做法是什么?

2 个答案:

答案 0 :(得分:11)

如果您指出某种错误,我通常会更喜欢例外情况。否则,您需要花费更多时间在代码库的不同级别上处理错误处理代码,而不是将错误处理集中在系统的适当层中 - 除其他原因外。

您可能会发现此old thread on perlmonks有用。我将在下面重现我的评论 - 因为我大多同意我当时所写的内容: - )


我喜欢例外的一些原因:

  • 稳健性。我可以忘记检查返回的错误值。我不能忘记检查一个例外。

  • 简洁。我更喜欢:

    $o->foo->bar->fribble->ni
    

    $o->foo or return(ERROR_FOO);
    $o->bar or return(ERROR_BAR);
    $o->fribble or return(ERROR_FRIBBLE);
    $o->ni or return(ERROR_NI);
    
  • 净度。对于基于异常的代码,“正常”控制流更加明确,因为它不会被错误处理代码遮挡。我认为上面两个代码示例中的第一个代码比第二个代码更直接地显示了代码的意图。

  • 分离关注点。错误条件和错误处理程序是不同的想法。

    • 您可能希望根据具体情况以不同方式处理错误。

    • 您可能也不知道错误应该如何处理。

    • 您可能不知道在编写代码时应如何处理错误。

    使用返回错误代码样式,您最终必须:

    • 传播错误条件,以便决定如何处理它们。

    • 将错误处理程序传播到可能发生错误的位置

    如果错误条件和错误处理程序之间存在许多级别的代码,则这两个选项都会迅速变得混乱。

  • 返回值和错误条件之间没有混淆。

可能还有更多; - )

答案 1 :(得分:1)

至少在制作的早期阶段,我喜欢大量的抛出 exeptions(早期的座右铭)。因此,我可以快速赶上任何错误(并节省大量时间,避免在逻辑和跟踪返回代码中思考)。然后在每次发布迭代中,我可以降低将它们与$ o->调试状态相关联的抛出的严重性。因此,当你运行你的测试时,死于所有事情,但当你运行你的代码真正的呱呱叫而不是日志,只有在不可避免的致命条件发生时才会死亡。在我的拙见中,我在过去使用的返回代码更加灵活。

有时候一个简单的'die'异常也不是很有用,所以最好有一个throw函数来打印所有的调用堆栈跟踪(比如Carp-> confess()| cluck())。

一个好的捕捉机制也很方便。使用Try::TinyTryCatch

PD:adrianh指出的perlmonk线程是经典的。