【发布时间】:2013-11-09 05:46:52
【问题描述】:
Perl 目前以这样一种方式实现$SIG{__DIE__},即使在 eval 块中,它也会捕获任何发生的错误。这有一个非常有用的属性,您可以在发生错误的确切位置停止代码,收集实际错误的堆栈跟踪,将其包装在一个对象中,然后以该对象作为参数手动调用 die。
这种对$SIG{__DIE__} 的滥用已被弃用。正式地,您应该将$SIG{__DIE__} 替换为*CORE::GLOBAL::die。但是,这两个不远程等效。 *CORE::GLOBAL::die 在发生运行时错误时被不调用!它所做的只是替换对die() 的显式调用。
我对更换模具不感兴趣。
我对捕捉运行时错误特别感兴趣。
我需要确保任何函数、任何深度、任何模块中的任何运行时错误都会导致 Perl 将控制权传递给我,以便我可以收集堆栈跟踪并重新抛出。这需要在 eval 块内工作——一个或多个封闭的 eval 块可能想要捕获异常,但运行时错误可能出现在没有封闭 eval 的函数中,在任何模块内,来自任何地方。
$SIG{__DIE__} 完美支持这一点——并且忠实地为我服务了几年或更长时间——但 Powers that Be™ 警告说,这个奇妙的设施随时可能被抢走,我不想要一个讨厌的总有一天会大吃一惊。
理想情况下,对于 Perl 本身,他们可以为此创建一个新信号 $SIG{__RTMERR__}(切换信号很容易,反正对我来说,因为它只挂在一个地方)。不幸的是,我的说服力不会导致酒鬼打开瓶子,所以假设这不会发生,那么究竟应该如何实现干净地捕获运行时错误的目标?
(例如,这里的另一个答案推荐 Carp::Always,这……也可以钩住 DIE!)
【问题讨论】:
标签: perl runtime-error