开发者

Detecting global destruction in Perl

开发者 https://www.devze.com 2023-02-08 09:58 出处:网络
I\'d like to detect if my object is being DESTROY\'d as part of global destruction, and prin开发者_StackOverflow社区t out a warning (as that\'d clearly be an error and lead to data loss). The obvious

I'd like to detect if my object is being DESTROY'd as part of global destruction, and prin开发者_StackOverflow社区t out a warning (as that'd clearly be an error and lead to data loss). The obvious way to do that would seem to be:

sub DESTROY {
    my $self = shift;
    # ⋮
    if (i_am_in_global_destruction()) {
        warn "I survived until global destruction";
    }
}

but I have been unable to find a good way to detect global destruction (instead of normal refcount hit 0 destruction).

By "good way", I mean not this, which though it works on 5.10.1 and 5.8.8, probably breaks the second someone gives it an odd glance:

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";
    }
}'


There's a module Devel::GlobalDestruction that uses a tiny bit of XS to let you get at the global destruction flag directly.

Update: since perl 5.14.0 there is a global variable ${^GLOBAL_PHASE} that will be set to "DESTRUCT" during global destruction. You should still generally use Devel::GlobalDestruction, since it works with perls back to 5.6. When installing on a perl with ${^GLOBAL_PHASE} it will use the built-in feature and not even require a C compiler to build.


A solution that is good enough for me is to set a flag in an END block.

package Whatever;
our $_IN_GLOBAL_DESTRUCTION = 0;
END {
    $_IN_GLOBAL_DESTRUCTION = 1;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消