Geo*_*Geo 4 perl exception-handling
我看到的代码如下:
do_something($param) || warn "something went wrong\n";
Run Code Online (Sandbox Code Playgroud)
我也看到了这样的代码:
eval {
do_something_else($param);
};
if($@) {
warn "something went wrong\n";
}
Run Code Online (Sandbox Code Playgroud)
我应该在所有子程序中使用eval/die吗?我应该根据子程序返回的内容编写所有代码吗?是不是eval代码(一遍又一遍)会让我慢下来?
hob*_*bbs 13
块eval不是字符串eval,所以不,它不慢.绝对推荐使用它.
虽然它的工作方式有一些令人烦恼的微妙之处(主要$@是全局变量这一事实令人讨厌的副作用),所以考虑使用Try :: Tiny而不是记住你需要eval防御性使用的所有小技巧.
Run Code Online (Sandbox Code Playgroud)do_something($param) || warn "something went wrong\n";
在这种情况下,do_something如果出现问题,预计会返回错误代码.要么它不能死,要么它死了,这是一个非常不寻常的情况.
Run Code Online (Sandbox Code Playgroud)eval { do_something_else($param); }; if($@) { warn "something went wrong\n"; }
在这里,假设do_something_else是通过抛出异常来传达出错的唯一机制.
如果do_something_else在真正异常情况下抛出异常并在其他一些情况下返回错误值,则还应检查其返回值.
使用eval的块形式不会在运行时引起额外的编译,因此没有严重的性能缺陷:
在第二种形式中,在块内的代码被解析一次-在同一时间环绕代码
eval本身被解析-和当前Perl程序的上下文内执行.此表单通常用于比第一个表单更有效地捕获异常(见下文),同时还提供BLOCK在编译时检查代码的好处.
模块warn非常烦人.成功或失败.不要在终端上打印东西然后继续运行; 我的程序无法根据您打印的某些消息采取措施.如果程序可以继续运行,只有在明确告知它没有问题时才打印一条消息.如果程序无法继续运行,die.这就是它的用途.
当出现问题时总是抛出异常.如果您可以解决问题,请修复它.如果你无法解决问题,请不要尝试; 抛出异常并让调用者处理它.(如果你不能处理你所呼叫的异常,请不要.)
基本上,许多程序出错的原因是因为他们试图修复他们无法解决的错误.在问题的第一个迹象下干净地死亡的程序易于调试和修复.一个在困惑时继续运行的程序只会破坏数据并使每个人烦恼.所以不要这样做.尽快死去.
你的两个例子完全不同.第一个检查错误的返回值,并采取一些响应操作.第二个检查被叫代码的实际死亡.
您必须自己决定哪种行为适合每种情况.我建议在大多数情况下简单地返回false.die如果您遇到严重到无法继续的错误(或者没有任何意义继续下去,那么您应该只明确说明,但即便如此,您仍然可以返回false).
包装块eval {}与包装任意代码不是一回事eval "".在前一种情况下,代码仍然在编译时解析,并且您不会产生任何额外的开销.您将简单地捕获该代码的任何死亡(但您不会有任何关于出现问题或代码有多远的指示,除了您留下的值$@).在后一种情况下,Perl解释器将代码视为一个简单的字符串,直到它被实际评估为止,因此在调用解释器时会有一定的成本(并且您将失去对代码的所有编译时检查).
顺便提一下,您调用eval和检查值的$@方式不是推荐的形式; 有关Perl中异常陷阱和技术的广泛讨论,请参阅此讨论.