X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FMeta%2FMethod%2FDestructor.pm;h=e06a13d240d2f7bdc5c2b30997c0d70743a7fba5;hb=054898323542f0f85865b5d8fad49c3f4ee982c6;hp=c6c60af6313d46da05297fa3022727cfac01c0b1;hpb=0f8380b0cdbda1e13ed7c456edd3f0d1c0315ec9;p=gitmo%2FMoose.git diff --git a/lib/Moose/Meta/Method/Destructor.pm b/lib/Moose/Meta/Method/Destructor.pm index c6c60af..e06a13d 100644 --- a/lib/Moose/Meta/Method/Destructor.pm +++ b/lib/Moose/Meta/Method/Destructor.pm @@ -4,11 +4,9 @@ package Moose::Meta::Method::Destructor; use strict; use warnings; +use Devel::GlobalDestruction (); use Scalar::Util 'blessed', 'weaken'; - -our $VERSION = '0.86'; -$VERSION = eval $VERSION; -our $AUTHORITY = 'cpan:STEVAN'; +use Try::Tiny; use base 'Moose::Meta::Method', 'Class::MOP::Method::Inlined'; @@ -30,6 +28,7 @@ sub new { 'name' => $options{name}, # ... 'options' => $options{options}, + 'definition_context' => $options{definition_context}, 'associated_metaclass' => $options{metaclass}, } => $class; @@ -76,68 +75,86 @@ sub _initialize_body { # requires some adaption on the part of # the author, after all, nothing is free) - my @DEMOLISH_methods = $self->associated_metaclass->find_all_methods_by_name('DEMOLISH'); - - my $source; - if ( @DEMOLISH_methods ) { - $source = 'sub {'; - - my @DEMOLISH_calls; - foreach my $method (@DEMOLISH_methods) { - push @DEMOLISH_calls => '$_[0]->' . $method->{class} . '::DEMOLISH()'; - } - - $source .= join ";\n" => @DEMOLISH_calls; + my $class = $self->associated_metaclass->name; + my @source = ( + 'sub {', + 'my $self = shift;', + 'return ' . $self->_generate_fallback_destructor('$self'), + 'if Scalar::Util::blessed($self) ne \'' . $class . '\';', + $self->_generate_DEMOLISHALL('$self'), + 'return;', + '}', + ); + warn join("\n", @source) if $self->options->{debug}; - $source .= ";\n" . '}'; - } else { - $source = 'sub { }'; + my $code = try { + $self->_compile_code(source => \@source); } + catch { + my $source = join("\n", @source); + $self->throw_error( + "Could not eval the destructor :\n\n$source\n\nbecause :\n\n$_", + error => $_, + data => $source, + ); + }; - warn $source if $self->options->{debug}; + $self->{'body'} = $code; +} - my ( $code, $e ) = $self->_compile_code( - environment => {}, - code => $source, - ); +sub _generate_fallback_destructor { + my $self = shift; + my ($inv) = @_; - $self->throw_error( - "Could not eval the destructor :\n\n$source\n\nbecause :\n\n$e", - error => $e, data => $source ) - if $e; + return $inv . '->Moose::Object::DESTROY(@_)'; +} - $self->{'body'} = $code; +sub _generate_DEMOLISHALL { + my $self = shift; + my ($inv) = @_; + + my @methods = $self->associated_metaclass->find_all_methods_by_name('DEMOLISH'); + return unless @methods; + + return ( + 'local $?;', + 'my $igd = Devel::GlobalDestruction::in_global_destruction;', + 'Try::Tiny::try {', + (map { $inv . '->' . $_->{class} . '::DEMOLISH($igd);' } @methods), + '}', + 'Try::Tiny::catch {', + 'die $_;', + '};', + ); } 1; +# ABSTRACT: Method Meta Object for destructors + __END__ =pod -=head1 NAME - -Moose::Meta::Method::Destructor - Method Meta Object for destructors - =head1 DESCRIPTION -This class is a subclass of L that +This class is a subclass of L that provides Moose-specific functionality for inlining destructors. To understand this class, you should read the the -L documentation as well. +L documentation as well. =head1 INHERITANCE C is a subclass of -L I L. +L I L. =head1 METHODS =over 4 -=item B<< Moose::Meta;:Method::Destructor->new(%options) >> +=item B<< Moose::Meta::Method::Destructor->new(%options) >> This constructs a new object. It accepts the following options: @@ -168,18 +185,9 @@ of its parents defines a C method, it needs a destructor. =back -=head1 AUTHORS - -Stevan Little Estevan@iinteractive.comE - -=head1 COPYRIGHT AND LICENSE - -Copyright 2006-2009 by Infinity Interactive, Inc. - -L +=head1 BUGS -This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. +See L for details on reporting bugs. =cut