这是我一位同事遇到的一个令人困惑的问题,我也无法找出原因。
简短的版本是,在他写的一个类中,定义了DESTROY
析构函数/方法,当对象被销毁时,DESTROY
不会被调用。它不会在我们认为对象超出范围的时候被调用。虽然我们考虑到可能在某个地方有一个对它的悬挂引用,但它不会在脚本退出时被调用。我们在类和脚本中添加了调试print
语句,甚至在END
块中显式调用了它,只是为了验证我们没有以某种方式将它放在错误的名称空间中。(我们没有。显式调用按预期触发了所有print
语句。)
所以我对此感到困惑,我和他一样对答案感兴趣。什么情况会导致这种行为?有问题的脚本正在干净地退出-没有调用POSIX::_exit
或类似的东西。唯一的“变量”是类正在使用Class::MethodMaker
来定义一些访问器和构造函数。然而,在Class::MethodMaker
文档中没有提到与类DESTROY
方法进行交互(或重写)。
4条答案
按热度按时间tzcvj98z1#
如果没有看到代码,就无法知道哪里出了问题。但我可以想象一个场景,看起来你的DESTROY()方法没有被调用:
此脚本将打印:
这个错误可能不像这个例子那么明显,die()调用可能在DESTROY代码的深处。
die()调用可能是由一些你没有想到的条件引起的。对象在全局销毁过程中以任意顺序被定义:
循环引用并不是必须的,一个对象检查它是否可以访问另一个对象,如果访问失败,抛出一个异常。
h2h,马蒂亚斯
zbdgwd5y2#
还有另一种不调用DESTROY的方式,它没有特别明确的文档记录。它只会在你编写守护进程之类的时候影响你。本质上,如果你的进程因为一个信号而死亡,(即使是CTRL-C,实际上是SIGINT),那么它就不会调用DESTROY方法。你可以通过使用一个只调用exit()的信号处理程序来让它这样做。在下面的例子中,如果程序正常退出,或者如果接收到SIGTERM,则调用DESTROY()方法:
gkn4icbw3#
刚刚发现在一个类中有一个以上的DESTROY子也会导致这种情况,看起来只有最后一个示例被调用。
9avjhtql4#
对
exec
的调用将不会调用Destroy: