X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP%2FClass.pm;h=d4f01037409f4121a3793d18632afa7e62f70013;hb=cacb672eae8fe9b02d53dc4e82c39091d401b4f8;hp=cc57b6c5be7c95e26de5d3c3149f8cd4f67c2731;hpb=42c0f0e16769c77535cec6ef4c4e66c3a16fce65;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP/Class.pm b/lib/Class/MOP/Class.pm index cc57b6c..d4f0103 100644 --- a/lib/Class/MOP/Class.pm +++ b/lib/Class/MOP/Class.pm @@ -11,7 +11,7 @@ use Class::MOP::Method::Wrapped; use Carp 'confess'; use Scalar::Util 'blessed', 'weaken'; -our $VERSION = '0.65'; +our $VERSION = '0.72'; $VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; @@ -250,9 +250,6 @@ sub create { my (%options) = @args; my $package_name = $options{package}; - (defined $package_name && $package_name) - || confess "You must pass a package name"; - (ref $options{superclasses} eq 'ARRAY') || confess "You must pass an ARRAY ref of superclasses" if exists $options{superclasses}; @@ -262,19 +259,21 @@ sub create { if exists $options{attributes}; (ref $options{methods} eq 'HASH') - || confess "You must pass an HASH ref of methods" + || confess "You must pass a HASH ref of methods" if exists $options{methods}; - my $code = "package $package_name;"; - $code .= "\$$package_name\:\:VERSION = '" . $options{version} . "';" - if exists $options{version}; - $code .= "\$$package_name\:\:AUTHORITY = '" . $options{authority} . "';" - if exists $options{authority}; + $class->SUPER::create(%options); - eval $code; - confess "creation of $package_name failed : $@" if $@; - - my $meta = $class->initialize($package_name); + my (%initialize_options) = @args; + delete @initialize_options{qw( + package + superclasses + attributes + methods + version + authority + )}; + my $meta = $class->initialize( $package_name => %initialize_options ); # FIXME totally lame $meta->add_method('meta' => sub { @@ -312,12 +311,12 @@ sub attribute_metaclass { $_[0]->{'attribute_metaclass'} } sub method_metaclass { $_[0]->{'method_metaclass'} } sub instance_metaclass { $_[0]->{'instance_metaclass'} } -# FIXME: -# this is a prime canidate for conversion to XS sub get_method_map { my $self = shift; - - my $current = Class::MOP::check_package_cache_flag($self->name); + + my $class_name = $self->name; + + my $current = Class::MOP::check_package_cache_flag($class_name); if (defined $self->{'_package_cache_flag'} && $self->{'_package_cache_flag'} == $current) { return $self->{'methods'} ||= {}; @@ -325,15 +324,14 @@ sub get_method_map { $self->{_package_cache_flag} = $current; - my $map = $self->{'methods'} ||= {}; + my $map = $self->{'methods'} ||= {}; - my $class_name = $self->name; my $method_metaclass = $self->method_metaclass; - my %all_code = $self->get_all_package_symbols('CODE'); + my $all_code = $self->get_all_package_symbols('CODE'); - foreach my $symbol (keys %all_code) { - my $code = $all_code{$symbol}; + foreach my $symbol (keys %{ $all_code }) { + my $code = $all_code->{$symbol}; next if exists $map->{$symbol} && defined $map->{$symbol} && @@ -500,6 +498,14 @@ sub superclasses { if (@_) { my @supers = @_; @{$self->get_package_symbol($var_spec)} = @supers; + + # NOTE: + # on 5.8 and below, we need to call + # a method to get Perl to detect + # a cycle in the class hierarchy + my $class = $self->name; + $class->isa($class); + # NOTE: # we need to check the metaclass # compatibility here so that we can @@ -637,15 +643,16 @@ sub add_method { $method->attach_to_class($self); - $self->get_method_map->{$method_name} = $method; + # This used to call get_method_map, which meant we would build all + # the method objects for the class just because we added one + # method. This is hackier, but quicker too. + $self->{methods}{$method_name} = $method; my $full_method_name = ($self->name . '::' . $method_name); $self->add_package_symbol( { sigil => '&', type => 'CODE', name => $method_name }, Class::MOP::subname($full_method_name => $body) ); - - $self->update_package_cache_flag; # still valid, since we just added the method to the map, and if it was invalid before that then get_method_map updated it } { @@ -729,7 +736,7 @@ sub has_method { (defined $method_name && $method_name) || confess "You must define a method name"; - exists $self->get_method_map->{$method_name}; + exists $self->{methods}{$method_name} || exists $self->get_method_map->{$method_name}; } sub get_method { @@ -743,7 +750,7 @@ sub get_method { # will just return undef for me now # return unless $self->has_method($method_name); - return $self->get_method_map->{$method_name}; + return $self->{methods}{$method_name} || $self->get_method_map->{$method_name}; } sub remove_method { @@ -1460,7 +1467,7 @@ for more information on the method metaclasses. Wrap a code ref (C<$attrs{body>) with C. -=item B +=item B This will take a C<$method_name> and CODE reference or meta method objectand install it into the class's package.