Release commit for 1.003001
[gitmo/Moo.git] / lib / Moo / Object.pm
index 1b26821..5012f79 100644 (file)
@@ -3,10 +3,20 @@ package Moo::Object;
 use strictures 1;
 
 our %NO_BUILD;
+our %NO_DEMOLISH;
 our $BUILD_MAKER;
+our $DEMOLISH_MAKER;
 
 sub new {
   my $class = shift;
+  unless (exists $NO_DEMOLISH{$class}) {
+    unless ($NO_DEMOLISH{$class} = !$class->can('DEMOLISH')) {
+      ($DEMOLISH_MAKER ||= do {
+        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};
@@ -45,43 +55,25 @@ sub BUILDALL {
   })->generate_method(ref($self)))}(@_);
 }
 
-sub DESTROY {
-    my $self = shift;
-
-    return unless $self->can('DEMOLISH'); # short circuit
-
-    require Moo::_Utils;
-
-    my $e = do {
-        local $?;
-        local $@;
-        eval {
-            # DEMOLISHALL
-
-            # We cannot count on being able to retrieve a previously made
-            # metaclass, _or_ being able to make a new one during global
-            # destruction. However, we should still be able to use mro at
-            # that time (at least tests suggest so ;)
-
-            foreach my $class (@{ Moo::_Utils::_get_linear_isa(ref $self) }) {
-                my $demolish = $class->can('DEMOLISH') || next;
-
-                $self->$demolish($Moo::_Utils::_in_global_destruction);
-            }
-        };
-        $@;
-    };
-
-    no warnings 'misc';
-    die $e if $e; # rethrow
+sub DEMOLISHALL {
+  my $self = shift;
+  $self->${\(($DEMOLISH_MAKER ||= do {
+    require Method::Generate::DemolishAll;
+    Method::Generate::DemolishAll->new
+  })->generate_method(ref($self)))}(@_);
 }
 
-
-
 sub does {
   require Role::Tiny;
   { no warnings 'redefine'; *does = \&Role::Tiny::does_role }
   goto &Role::Tiny::does_role;
 }
 
+# duplicated in Moo::Role
+sub meta {
+  require Moo::HandleMoose::FakeMetaClass;
+  my $class = ref($_[0])||$_[0];
+  bless({ name => $class }, 'Moo::HandleMoose::FakeMetaClass');
+}
+
 1;