编写 Perl 模块时,使用 croak/die 是否是一种好的实践?
毕竟,如果调用者没有使用 eval 块,模块可能会使调用它的程序崩溃。
在这些情况下,最佳实践是什么?
我喜欢异常的一些原因:
Robustness. I can forget to check for an returned error value. I cannot forget to check for an exception.
Brevity. I prefer:
$o->foo->bar->fribble->ni
to
$o->foo or return(ERROR_FOO);
$o->bar or return(ERROR_BAR);
$o->fribble or return(ERROR_FRIBBLE);
$o->ni or return(ERROR_NI);
Clarity. With exception based code the "normal" flow of control is more explicit because it is not obscured by error handling code. I think that the first of the two code examples above shows the intent of the code more directly than the second does.
Separation of concerns. The error condition and the error handler are different ideas.
You may want an error to be handled in different ways depending on the context.
You may also not know how the error should be handled at the point it occurs.
You may not know how the error should be handled at the time you write the code.
With the return-error-code style you end up having to either:
propogate error conditions to where the decision on how they should be handled can be made.
propogating error handlers down to where the errors may occur
Both options rapidly become messy if there are many levels of code between the error condition and the error handler.
No confusion between return values and error conditions.
我相信还有更多的;-)
至少在生产的早期阶段,我喜欢有大量的抛出异常(尽早死亡的座右铭)。这样我就可以快速捕捉到任何错误(并节省您大量的时间,避免思考逻辑和跟踪返回代码)。然后在每个发布迭代中,我可以通过将它们与$ o->debug状态相关联来降低抛出的严重性。因此,当您运行测试时,一切都会死亡,但是当您真正运行代码时,会将其转换为日志并仅在不可避免的致命条件发生时才死亡。在我看来,这比我过去使用的返回代码更灵活。
另外,有时候一个简单的“die”异常并不是很有用,所以最好有一个抛出函数,可以打印所有调用堆栈跟踪(例如Carp->confess()|cluck())。
还有一个好的捕获机制也很方便。使用Try::Tiny或TryCatch。
附:adrianh指出的perlmonk线程是经典之作。