From: Matt S Trout Date: Mon, 14 May 2012 20:29:52 +0000 (+0000) Subject: inline Devel::GlobalDestruction pure perl code temporarily X-Git-Tag: v0.091005~3 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=19e0e7494654a7aa180272206fc8581f7030e0cb;p=gitmo%2FMoo.git inline Devel::GlobalDestruction pure perl code temporarily --- diff --git a/Changes b/Changes index 215507d..4962303 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,5 @@ + - temporary switch to an inlined in_global_destruction to avoid needing + to fatpack Sub::Exporter for features we don't use - a weakened value should still be returned on set (fixes lazy + weak_ref) - add an explicit return to all exported subs so people don't accidentally rely on the return value diff --git a/Makefile.PL b/Makefile.PL index e9e9562..86745bc 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -14,7 +14,6 @@ my %RUN_DEPS = ( 'strictures' => 1.001001, 'Module::Runtime' => 0.013, 'Role::Tiny' => 1.001001, - 'Devel::GlobalDestruction' => '0.05', ); # have to do this since old EUMM dev releases miss the eval $VERSION line diff --git a/lib/Method/Generate/DemolishAll.pm b/lib/Method/Generate/DemolishAll.pm index 3d499cc..5d45656 100644 --- a/lib/Method/Generate/DemolishAll.pm +++ b/lib/Method/Generate/DemolishAll.pm @@ -21,7 +21,7 @@ sub generate_method { local $@; require Moo::_Utils; eval { - $self->DEMOLISHALL(Devel::GlobalDestruction::in_global_destruction); + $self->DEMOLISHALL(Moo::_Utils::_in_global_destruction); }; $@; }; diff --git a/lib/Moo/_Utils.pm b/lib/Moo/_Utils.pm index 34aad9a..7c2a8f8 100644 --- a/lib/Moo/_Utils.pm +++ b/lib/Moo/_Utils.pm @@ -10,15 +10,17 @@ use constant can_haz_subname => eval { require Sub::Name }; use strictures 1; use Module::Runtime qw(require_module); -use Devel::GlobalDestruction; use base qw(Exporter); use Moo::_mro; our @EXPORT = qw( _getglob _install_modifier _load_module _maybe_load_module _get_linear_isa _getstash _install_coderef _name_coderef + _in_global_destruction ); +sub _in_global_destruction; + sub _install_modifier { my ($into, $type, $name, $code) = @_; @@ -78,7 +80,7 @@ sub STANDARD_DESTROY { local $?; local $@; eval { - $self->DEMOLISHALL(in_global_destruction); + $self->DEMOLISHALL(_in_global_destruction); }; $@; }; @@ -87,4 +89,50 @@ sub STANDARD_DESTROY { die $e if $e; # rethrow } +if (defined ${^GLOBAL_PHASE}) { + eval 'sub _in_global_destruction () { ${^GLOBAL_PHASE} eq q[DESTRUCT] }'; +} else { + eval <<'PP_IGD' or die $@; + +my ($in_global_destruction, $before_is_installed); + +sub _in_global_destruction { $in_global_destruction } + +END { + # SpeedyCGI runs END blocks every cycle but somehow keeps object instances + # hence lying about it seems reasonable...ish + $in_global_destruction = 1 unless $CGI::SpeedyCGI::i_am_speedy; +} + +# threads do not execute the global ENDs (it would be stupid). However +# one can register a new END via simple string eval within a thread, and +# achieve the same result. A logical place to do this would be CLONE, which +# is claimed to run in the context of the new thread. However this does +# not really seem to be the case - any END evaled in a CLONE is ignored :( +# Hence blatantly hooking threads::create + +if ($INC{'threads.pm'}) { + my $orig_create = threads->can('create'); + no warnings 'redefine'; + *threads::create = sub { + { local $@; eval 'END { $in_global_destruction = 1 }' }; + goto $orig_create; + }; + $before_is_installed = 1; +} + +# just in case threads got loaded after us (silly) +sub CLONE { + unless ($before_is_installed) { + require Carp; + Carp::croak("You must load the 'threads' module before @{[ __PACKAGE__ ]}"); + } +} + +1; # keep eval happy + +PP_IGD + +} + 1; diff --git a/lib/Moo/sification.pm b/lib/Moo/sification.pm index 2f94663..baf4c52 100644 --- a/lib/Moo/sification.pm +++ b/lib/Moo/sification.pm @@ -1,12 +1,12 @@ package Moo::sification; use strictures 1; -use Devel::GlobalDestruction; +use Moo::_Utils (); sub unimport { our $disarmed = 1 } sub Moo::HandleMoose::AuthorityHack::DESTROY { - unless (our $disarmed or in_global_destruction) { + unless (our $disarmed or Moo::_Utils::_in_global_destruction) { require Moo::HandleMoose; Moo::HandleMoose->import; }