我想检测我的对象是否DESTROY
作为全局销毁的一部分,并打印出警告(因为这显然是一个错误并导致数据丢失)。显而易见的方法似乎是:
sub DESTROY {
my $self = shift;
# ⋮
if (i_am_in_global_destruction()) {
warn "I survived until global destruction";
}
}
但我一直无法找到一种检测全局破坏的好方法(而不是正常的refcount命中0破坏)。
通过“好方法”,我的意思不是这个,虽然它适用于5.10.1和5.8.8,但可能打破第二个人给它一个奇怪的目光:
sub DESTROY {
$in_gd = 0;
{
local $SIG{__WARN__} = sub { $_[0] =~ /during global destruction\.$/ and $in_gd = 1 };
warn "look, a warning";
}
if ($in_gd) {
warn "I survived until global destruction";
}
}'
答案 0 :(得分:10)
有一个模块Devel::GlobalDestruction使用一点点XS来让你直接获得全局销毁标记。
更新:自perl 5.14.0以来,全局变量${^GLOBAL_PHASE}
将在全局销毁期间设置为"DESTRUCT"
。你仍然应该使用Devel :: GlobalDestruction,因为它可以与perls一起使用回5.6。在使用${^GLOBAL_PHASE}
的perl上安装时,它将使用内置功能,甚至不需要构建C编译器。
答案 1 :(得分:8)
对我来说足够好的解决方案是在END
块中设置标记。
package Whatever;
our $_IN_GLOBAL_DESTRUCTION = 0;
END {
$_IN_GLOBAL_DESTRUCTION = 1;
}