12

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!)

4

1 回答 1

3

去做就对了。我已经做到了。可能知道这个钩子的每个人都做过。

这是Perl ; 几十年前它仍然兼容。我在这里将“弃用”解释为“如果您不需要它,请不要使用它,呃,恶心”。但是您确实需要它,并且似乎理解其中的含义,所以我选择了它。我严重怀疑一个不可替代的语言功能很快就会消失。

并在 CPAN 上发布你的工作,这样下一个开发人员就不需要再重新发明它了。:)

于 2013-10-30T03:37:09.440 回答