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};
})->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;