| Class-MOP documentation | Contained in the Class-MOP distribution. |
Class::MOP::Method - Method Meta Object
The Method Protocol is very small, since methods in Perl 5 are just subroutines in a specific package. We provide a very basic introspection interface.
This is the constructor. It accepts a method body in the form of either a code reference or a Class::MOP::Method instance, followed by a hash of options.
The options are:
The method name (without a package name). This is required if $code
is a coderef.
The package name for the method. This is required if $code is a
coderef.
An optional Class::MOP::Class object. This is the metaclass for the method's class.
This makes a shallow clone of the method object. In particular, subroutine reference itself is shared between all clones of a given method.
When a method is cloned, the original method object will be available
by calling original_method on the clone.
This returns a reference to the method's subroutine.
This returns the method's name
This returns the method's package name.
This returns the method's fully qualified name (package name and method name).
This returns the Class::MOP::Class object for the method, if one exists.
If this method object was created as a clone of some other method object, this returns the object that was cloned.
This returns the method's original name, wherever it was first defined.
If this method is a clone of a clone (of a clone, etc.), this method returns the name from the first method in the chain of clones.
This returns the method's original package name, wherever it was first defined.
If this method is a clone of a clone (of a clone, etc.), this method returns the package name from the first method in the chain of clones.
This returns the method's original fully qualified name, wherever it was first defined.
If this method is a clone of a clone (of a clone, etc.), this method returns the fully qualified name from the first method in the chain of clones.
Given a Class::MOP::Class object, this method sets the associated metaclass for the method. This will overwrite any existing associated metaclass.
Removes any associated metaclass object for the method.
This executes the method. Any arguments provided will be passed on to the method itself.
This will return a Class::MOP::Class instance for this class.
It should also be noted that Class::MOP will actually bootstrap this module by installing a number of attribute meta-objects into its metaclass.
Stevan Little <stevan@iinteractive.com>
Copyright 2006-2010 by Infinity Interactive, Inc.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Class-MOP documentation | Contained in the Class-MOP distribution. |
package Class::MOP::Method; use strict; use warnings; use Carp 'confess'; use Scalar::Util 'weaken', 'reftype', 'blessed'; our $VERSION = '1.12'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; use base 'Class::MOP::Object'; # NOTE: # if poked in the right way, # they should act like CODE refs. use overload '&{}' => sub { $_[0]->body }, fallback => 1; # construction sub wrap { my ( $class, @args ) = @_; unshift @args, 'body' if @args % 2 == 1; my %params = @args; my $code = $params{body}; 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"; my $self = $class->_new(\%params); weaken($self->{associated_metaclass}) if $self->{associated_metaclass}; return $self; } sub _new { my $class = shift; return Class::MOP::Class->initialize($class)->new_object(@_) if $class ne __PACKAGE__; my $params = @_ == 1 ? $_[0] : {@_}; return bless { 'body' => $params->{body}, 'associated_metaclass' => $params->{associated_metaclass}, 'package_name' => $params->{package_name}, 'name' => $params->{name}, 'original_method' => $params->{original_method}, } => $class; } ## accessors sub associated_metaclass { shift->{'associated_metaclass'} } sub attach_to_class { my ( $self, $class ) = @_; $self->{associated_metaclass} = $class; weaken($self->{associated_metaclass}); } sub detach_from_class { my $self = shift; delete $self->{associated_metaclass}; } sub fully_qualified_name { my $self = shift; $self->package_name . '::' . $self->name; } sub original_method { (shift)->{'original_method'} } sub _set_original_method { $_[0]->{'original_method'} = $_[1] } # It's possible that this could cause a loop if there is a circular # reference in here. That shouldn't ever happen in normal # circumstances, since original method only gets set when clone is # called. We _could_ check for such a loop, but it'd involve some sort # of package-lexical variable, and wouldn't be terribly subclassable. sub original_package_name { my $self = shift; $self->original_method ? $self->original_method->original_package_name : $self->package_name; } sub original_name { my $self = shift; $self->original_method ? $self->original_method->original_name : $self->name; } sub original_fully_qualified_name { my $self = shift; $self->original_method ? $self->original_method->original_fully_qualified_name : $self->fully_qualified_name; } sub execute { my $self = shift; $self->body->(@_); } # 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; __END__