【问题标题】:Catching runtime errors in Perl and converting to exceptions在 Perl 中捕获运行时错误并转换为异常
【发布时间】: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


    【解决方案1】:

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

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

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

    【讨论】:

    • 它已被弃用多年,但到目前为止,还没有说明替代品。这要么意味着它没有被弃用,要么他们不打算保留该功能,或者他们只是忽略了说明正确的方法。如果重要的事情是实现某事的唯一方法,那么您就不能弃用它!也许他们不会...
    • 根据a search on grep.cpan.me“超过1000个发行版”正在使用$SIG{__DIE__}。我不认为它会去......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2014-11-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    相关资源
    最近更新 更多