move to early generation of DESTROY/DEMOLISHALL where possible and hope like hell...
Matt S Trout [Mon, 3 Oct 2011 05:30:18 +0000 (05:30 +0000)]
Changes
lib/Method/Generate/Constructor.pm
lib/Method/Generate/DemolishAll.pm
lib/Moo/Object.pm

diff --git a/Changes b/Changes
index 61c642e..c0928ed 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,3 +1,4 @@
+  - add support for DEMOLISH
   - add support for BUILDARGS
 
 0.009010 - 2011-07-20
index e4f7b1f..11f0589 100644 (file)
@@ -60,6 +60,10 @@ sub generate_method {
     );
   }
   $body .= '    return $new;'."\n";
+  if ($into->can('DEMOLISH')) {
+    { local $@; require Method::Generate::DemolishAll; }
+    Method::Generate::DemolishAll->new->generate_method($into);
+  }
   quote_sub
     "${into}::${name}" => $body,
     $self->{captures}, $quote_opts||{}
index 0126680..0ad1f58 100644 (file)
@@ -13,6 +13,21 @@ sub generate_method {
     qq{    my \$self = shift;\n},
     $self->demolishall_body_for($into, '$self', '@_'),
     qq{    return \$self\n};
+  quote_sub "${into}::DESTROY", join '',
+    q!    my $self = shift;
+    my $e = do {
+      local $?;
+      local $@;
+      require Moo::_Utils;
+      eval {
+        $self->DEMOLISHALL($Moo::_Utils::_in_global_destruction);
+      };
+      $@;
+    };
+  
+    no warnings 'misc';
+    die $e if $e; # rethrow
+  !;
 }
 
 sub demolishall_body_for {
index fb7415d..04d7f7e 100644 (file)
@@ -9,6 +9,14 @@ our $DEMOLISH_MAKER;
 
 sub new {
   my $class = shift;
+  unless (exists $NO_DEMOLISH{$class}) {
+    unless ($NO_DEMOLISH{$class} = !$class->can('DEMOLISH')) {
+      ($DEMOLISH_MAKER ||= do {
+        { local $@; require Method::Generate::DemolishAll; }
+        Method::Generate::DemolishAll->new
+      })->generate_method($class);
+    }
+  }
   $NO_BUILD{$class} and
     return bless({ ref($_[0]) eq 'HASH' ? %{$_[0]} : @_ }, $class);
   $NO_BUILD{$class} = !$class->can('BUILD') unless exists $NO_BUILD{$class};
@@ -55,30 +63,6 @@ sub DEMOLISHALL {
   })->generate_method(ref($self)))}(@_);
 }
 
-sub DESTROY {
-  my $self = shift;
-
-  my $class = ref($self);
-
-  $NO_DEMOLISH{$class} = !$class->can('DEMOLISH')
-    unless exists $NO_DEMOLISH{$class};
-
-  return if $NO_DEMOLISH{$class};
-
-  my $e = do {
-    local $?;
-    local $@;
-    require Moo::_Utils;
-    eval {
-      $self->DEMOLISHALL($Moo::_Utils::_in_global_destruction);
-    };
-    $@;
-  };
-
-  no warnings 'misc';
-  die $e if $e; # rethrow
-}
-
 sub does {
   { local $@; require Role::Tiny; }
   { no warnings 'redefine'; *does = \&Role::Tiny::does_role }