X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP%2FMethod.pm;h=aa252281525d0c515737136a8c274f27712104eb;hb=e41d1dd685584e6461d9198a9478404025022e29;hp=c6e7afc34dd807e2313da18343841a6d01d0953a;hpb=3cf189f335625b5ceb9ba49895ee9c78af07dbaa;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP/Method.pm b/lib/Class/MOP/Method.pm index c6e7afc..aa25228 100644 --- a/lib/Class/MOP/Method.pm +++ b/lib/Class/MOP/Method.pm @@ -5,9 +5,9 @@ use strict; use warnings; use Carp 'confess'; -use Scalar::Util 'weaken', 'reftype'; +use Scalar::Util 'weaken', 'reftype', 'blessed'; -our $VERSION = '0.89'; +our $VERSION = '1.06'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; @@ -28,8 +28,15 @@ sub wrap { my %params = @args; my $code = $params{body}; - (ref $code && 'CODE' eq reftype($code)) - || confess "You must supply a CODE reference to bless, not (" . ($code || 'undef') . ")"; + if (blessed($code) && $code->isa(__PACKAGE__)) { + my $method = $code->clone; + delete $params{body}; + Class::MOP::class_of($class)->rebless_instance($method, %params); + return $method; + } + elsif (!ref $code || 'CODE' ne reftype($code)) { + confess "You must supply a CODE reference to bless, not (" . ($code || 'undef') . ")"; + } ($params{package_name} && $params{name}) || confess "You must supply the package_name and name parameters"; @@ -43,13 +50,18 @@ sub wrap { sub _new { my $class = shift; + + return Class::MOP::Class->initialize($class)->new_object(@_) + if $class ne __PACKAGE__; + my $params = @_ == 1 ? $_[0] : {@_}; - my $self = bless { + return bless { 'body' => $params->{body}, 'associated_metaclass' => $params->{associated_metaclass}, 'package_name' => $params->{package_name}, 'name' => $params->{name}, + 'original_method' => $params->{original_method}, } => $class; } @@ -57,25 +69,6 @@ sub _new { sub associated_metaclass { shift->{'associated_metaclass'} } -sub _is_valid_generation{ - my($self) = @_; - my $metaclass = $self->associated_metaclass; - - if($metaclass){ - return( ($self->{_generation} || 0) == Class::MOP::check_package_cache_flag($metaclass->name) ); - } - else{ - return 1; - } -} - -sub _update_generation { - my($self) = @_; - my $metaclass = $self->associated_metaclass - or confess("No metaclass associated to the method " . $self->name); - $self->{_generation} = Class::MOP::check_package_cache_flag($metaclass->name); -} - sub attach_to_class { my ( $self, $class ) = @_; $self->{associated_metaclass} = $class; @@ -130,11 +123,19 @@ sub execute { $self->body->(@_); } -# NOTE: -# the Class::MOP bootstrap -# will create this for us -# - SL -# sub clone { ... } +# We used to go through use Class::MOP::Class->clone_instance to do this, but +# this was awfully slow. This method may be called a number of times when +# classes are loaded (especially during Moose role application), so it is +# worth optimizing. - DR +sub clone { + my $self = shift; + + my $clone = bless { %{$self}, @_ }, blessed($self); + + $clone->_set_original_method($self); + + return $clone; +} 1; @@ -158,8 +159,9 @@ introspection interface. =item B<< Class::MOP::Method->wrap($code, %options) >> -This is the constructor. It accepts a subroutine reference and a hash -of options. +This is the constructor. It accepts a method body in the form of +either a code reference or a L instance, followed +by a hash of options. The options are: @@ -167,11 +169,13 @@ The options are: =item * name -The method name (without a package name). This is required. +The method name (without a package name). This is required if C<$code> +is a coderef. =item * package_name -The package name for the method. This is required. +The package name for the method. This is required if C<$code> is a +coderef. =item * associated_metaclass @@ -273,7 +277,7 @@ Stevan Little Estevan@iinteractive.comE =head1 COPYRIGHT AND LICENSE -Copyright 2006-2009 by Infinity Interactive, Inc. +Copyright 2006-2010 by Infinity Interactive, Inc. L