Version 0.12
[p5sagit/Devel-GlobalDestruction.git] / lib / Devel / GlobalDestruction.pm
CommitLineData
a91e8a78 1package Devel::GlobalDestruction;
2
3use strict;
4use warnings;
5
5936cc83 6our $VERSION = '0.12';
a91e8a78 7
aaccce0c 8use Sub::Exporter::Progressive -setup => {
53daa838 9 exports => [ qw(in_global_destruction) ],
10 groups => { default => [ -all ] },
a91e8a78 11};
12
6e3fd33e 13# we run 5.14+ - everything is in core
14#
eaac10b5 15if (defined ${^GLOBAL_PHASE}) {
62376bb4 16 eval 'sub in_global_destruction () { ${^GLOBAL_PHASE} eq q[DESTRUCT] }; 1'
17 or die $@;
3790e928 18}
6e3fd33e 19# try to load the xs version if it was compiled
20#
9aaf3646 21elsif (eval {
b1bee216 22 require Devel::GlobalDestruction::XS;
d4be4bd8 23 no warnings 'once';
b1bee216 24 *in_global_destruction = \&Devel::GlobalDestruction::XS::in_global_destruction;
53daa838 25 1;
9aaf3646 26}) {
53daa838 27 # the eval already installed everything, nothing to do
3790e928 28}
9aaf3646 29else {
350bef65 30 # internally, PL_main_cv is set to Nullcv immediately before entering
31 # global destruction and we can use B to detect that. B::main_cv will
32 # only ever be a B::CV or a B::SPECIAL that is a reference to 0
97415ced 33 require B;
350bef65 34 eval 'sub in_global_destruction () { ${B::main_cv()} == 0 }; 1'
97415ced 35 or die $@;
9aaf3646 36}
37
381; # keep require happy
39
40
41__END__
a91e8a78 42
43=head1 NAME
44
753fd2ff 45Devel::GlobalDestruction - Provides function returning the equivalent of
46C<${^GLOBAL_PHASE} eq 'DESTRUCT'> for older perls.
a91e8a78 47
48=head1 SYNOPSIS
49
f832e240 50 package Foo;
51 use Devel::GlobalDestruction;
a91e8a78 52
f832e240 53 use namespace::clean; # to avoid having an "in_global_destruction" method
a91e8a78 54
f832e240 55 sub DESTROY {
56 return if in_global_destruction;
a91e8a78 57
f832e240 58 do_something_a_little_tricky();
59 }
a91e8a78 60
61=head1 DESCRIPTION
62
63Perl's global destruction is a little tricky to deal with WRT finalizers
64because it's not ordered and objects can sometimes disappear.
65
66Writing defensive destructors is hard and annoying, and usually if global
ead5da2b 67destruction is happening you only need the destructors that free up non
a91e8a78 68process local resources to actually execute.
69
70For these constructors you can avoid the mess by simply bailing out if global
71destruction is in effect.
72
73=head1 EXPORTS
74
aaccce0c 75This module uses L<Sub::Exporter::Progressive> so the exports may be renamed,
76aliased, etc. if L<Sub::Exporter> is present.
a91e8a78 77
78=over 4
79
80=item in_global_destruction
81
761f3ee2 82Returns true if the interpreter is in global destruction. In perl 5.14+, this
6f93d768 83returns C<${^GLOBAL_PHASE} eq 'DESTRUCT'>, and on earlier perls, detects it using
350bef65 84the value of C<PL_main_cv> or C<PL_dirty>.
a91e8a78 85
86=back
87
ec94b9e1 88=head1 AUTHORS
a91e8a78 89
90Yuval Kogman E<lt>nothingmuch@woobling.orgE<gt>
91
ec94b9e1 92Florian Ragwitz E<lt>rafl@debian.orgE<gt>
93
aaa7f60f 94Jesse Luehrs E<lt>doy@tozt.netE<gt>
95
9aaf3646 96Peter Rabbitson E<lt>ribasushi@cpan.orgE<gt>
97
aaccce0c 98Arthur Axel 'fREW' Schmidt E<lt>frioux@gmail.comE<gt>
99
140a3884 100Elizabeth Mattijsen E<lt>liz@dijkmat.nlE<gt>
101
5ed10b49 102Greham Knop E<lt>haarg@haarg.orgE<gt>
103
a91e8a78 104=head1 COPYRIGHT
105
f832e240 106 Copyright (c) 2008 Yuval Kogman. All rights reserved
107 This program is free software; you can redistribute
108 it and/or modify it under the same terms as Perl itself.
a91e8a78 109
110=cut