X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FClass%2FMOP.pm;h=c1f76427b457887bd3462769df6910f484c927e4;hb=94278c1ba6283af20c09a6aef615954825d08162;hp=20ca98e451d635755e5d4f63e8e655c213d88c93;hpb=45582002453c2abd8fb358894933d9094ed2cbe3;p=gitmo%2FClass-MOP.git diff --git a/lib/Class/MOP.pm b/lib/Class/MOP.pm index 20ca98e..c1f7642 100644 --- a/lib/Class/MOP.pm +++ b/lib/Class/MOP.pm @@ -4,13 +4,13 @@ package Class::MOP; use strict; use warnings; +use 5.008; + use MRO::Compat; use Carp 'confess'; use Scalar::Util 'weaken'; -use Sub::Identify 'get_code_info'; - BEGIN { local $@; eval { @@ -26,7 +26,7 @@ BEGIN { require Devel::GlobalDestruction; Devel::GlobalDestruction->import("in_global_destruction"); 1; - } or *in_global_destruction = sub () { '' }; + } or *in_global_destruction = sub () { !1 }; } @@ -47,23 +47,40 @@ BEGIN { } our $VERSION = '0.65'; +our $XS_VERSION = $VERSION; +$VERSION = eval $VERSION; our $AUTHORITY = 'cpan:STEVAN'; # after that everything is loaded, if we're allowed try to load faster XS # versions of various things -unless ($ENV{CLASS_MOP_NO_XS}) { +_try_load_xs() or _load_pure_perl(); + +sub _try_load_xs { + return if $ENV{CLASS_MOP_NO_XS}; + my $e = do { local $@; eval { require XSLoader; - __PACKAGE__->XSLoader::load($VERSION); + # just doing this - no warnings 'redefine' - doesn't work + # for some reason + local $^W = 0; + __PACKAGE__->XSLoader::load($XS_VERSION); }; $@; }; die $e if $e && $e !~ /object version|loadable object/; + + return $e ? 0 : 1; +} + +sub _load_pure_perl { + require Sub::Identify; + Sub::Identify->import('get_code_info'); } + { # Metaclasses are singletons, so we cache them here. # there is no need to worry about destruction though @@ -92,7 +109,7 @@ unless ($ENV{CLASS_MOP_NO_XS}) { sub load_class { my $class = shift; - if (ref($class) || !defined($class) || !length($class)) { + unless ( _is_valid_class_name($class) ) { my $display = defined($class) ? $class : 'undef'; confess "Invalid class name ($display)"; } @@ -100,9 +117,7 @@ sub load_class { # if the class is not already loaded in the symbol table.. unless (is_class_loaded($class)) { # require it - my $file = $class . '.pm'; - $file =~ s{::}{/}g; - my $e = do { local $@; eval { require($file) }; $@ }; + my $e = do { local $@; eval "require $class"; $@ }; confess "Could not load class ($class) because : $e" if $e; } @@ -115,6 +130,18 @@ sub load_class { return get_metaclass_by_name($class) if defined wantarray; } +sub _is_valid_class_name { + my $class = shift; + + return 0 if ref($class); + return 0 unless defined($class); + return 0 unless length($class); + + return 1 if $class =~ /^\w+(?:::\w+)*$/; + + return 0; +} + sub is_class_loaded { my $class = shift; @@ -208,15 +235,6 @@ Class::MOP::Package->meta->add_attribute( )) ); -# NOTE: -# use the metaclass to construct the meta-package -# which is a superclass of the metaclass itself :P -Class::MOP::Package->meta->add_method('initialize' => sub { - my $class = shift; - my $package_name = shift; - $class->meta->new_object('package' => $package_name, @_); -}); - ## -------------------------------------------------------- ## Class::MOP::Module @@ -451,40 +469,6 @@ Class::MOP::Attribute->meta->add_attribute( )) ); -# NOTE: (meta-circularity) -# This should be one of the last things done -# it will "tie the knot" with Class::MOP::Attribute -# so that it uses the attributes meta-objects -# to construct itself. -Class::MOP::Attribute->meta->add_method('new' => sub { - my ( $class, @args ) = @_; - - unshift @args, "name" if @args % 2 == 1; - my %options = @args; - - my $name = $options{name}; - - (defined $name && $name) - || confess "You must provide a name for the attribute"; - $options{init_arg} = $name - if not exists $options{init_arg}; - - if(exists $options{builder}){ - confess("builder must be a defined scalar value which is a method name") - if ref $options{builder} || !(defined $options{builder}); - confess("Setting both default and builder is not allowed.") - if exists $options{default}; - } else { - (Class::MOP::Attribute::is_default_a_coderef(\%options)) - || confess("References are not allowed as default values, you must ". - "wrap the default of '$name' in a CODE reference (ex: sub { [] } and not [])") - if exists $options{default} && ref $options{default}; - } - - # return the new object - $class->meta->new_object(%options); -}); - Class::MOP::Attribute->meta->add_method('clone' => sub { my $self = shift; $self->meta->clone_object($self, @_); @@ -516,25 +500,6 @@ Class::MOP::Method->meta->add_attribute( )) ); -# FIMXE prime candidate for immutablization -Class::MOP::Method->meta->add_method('wrap' => sub { - my ( $class, @args ) = @_; - - unshift @args, 'body' if @args % 2 == 1; - - my %options = @args; - my $code = $options{body}; - - ('CODE' eq ref($code)) - || confess "You must supply a CODE reference to bless, not (" . ($code || 'undef') . ")"; - - ($options{package_name} && $options{name}) - || confess "You must supply the package_name and name parameters"; - - # return the new object - $class->meta->new_object(%options); -}); - Class::MOP::Method->meta->add_method('clone' => sub { my $self = shift; $self->meta->clone_object($self, @_); @@ -562,15 +527,6 @@ Class::MOP::Method::Generated->meta->add_attribute( )) ); -Class::MOP::Method::Generated->meta->add_method('new' => sub { - my ($class, %options) = @_; - ($options{package_name} && $options{name}) - || confess "You must supply the package_name and name parameters"; - my $self = $class->meta->new_object(%options); - $self->initialize_body; - $self; -}); - ## -------------------------------------------------------- ## Class::MOP::Method::Accessor @@ -588,36 +544,6 @@ Class::MOP::Method::Accessor->meta->add_attribute( )) ); -Class::MOP::Method::Accessor->meta->add_method('new' => sub { - my $class = shift; - my %options = @_; - - (exists $options{attribute}) - || confess "You must supply an attribute to construct with"; - - (exists $options{accessor_type}) - || confess "You must supply an accessor_type to construct with"; - - (Scalar::Util::blessed($options{attribute}) && $options{attribute}->isa('Class::MOP::Attribute')) - || confess "You must supply an attribute which is a 'Class::MOP::Attribute' instance"; - - ($options{package_name} && $options{name}) - || confess "You must supply the package_name and name parameters"; - - # return the new object - my $self = $class->meta->new_object(%options); - - # we don't want this creating - # a cycle in the code, if not - # needed - Scalar::Util::weaken($self->{'attribute'}); - - $self->initialize_body; - - $self; -}); - - ## -------------------------------------------------------- ## Class::MOP::Method::Constructor @@ -639,30 +565,6 @@ Class::MOP::Method::Constructor->meta->add_attribute( )) ); -Class::MOP::Method::Constructor->meta->add_method('new' => sub { - my $class = shift; - my %options = @_; - - (Scalar::Util::blessed $options{metaclass} && $options{metaclass}->isa('Class::MOP::Class')) - || confess "You must pass a metaclass instance if you want to inline" - if $options{is_inline}; - - ($options{package_name} && $options{name}) - || confess "You must supply the package_name and name parameters"; - - # return the new object - my $self = $class->meta->new_object(%options); - - # we don't want this creating - # a cycle in the code, if not - # needed - Scalar::Util::weaken($self->{'associated_metaclass'}); - - $self->initialize_body; - - $self; -}); - ## -------------------------------------------------------- ## Class::MOP::Instance @@ -687,7 +589,7 @@ Class::MOP::Instance->meta->add_attribute( Class::MOP::Instance->meta->add_attribute( Class::MOP::Attribute->new('attributes', - reader => { attributes => \&Class::MOP::Instance::attributes }, + reader => { attributes => \&Class::MOP::Instance::get_all_attributes }, ), ); @@ -708,17 +610,6 @@ Class::MOP::Instance->meta->add_attribute( # for the constructor to be able to use it Class::MOP::Instance->meta->get_meta_instance; -Class::MOP::Instance->meta->add_method('new' => sub { - my $class = shift; - my $options = $class->BUILDARGS(@_); - - my $self = $class->meta->new_object(%$options); - - Scalar::Util::weaken($self->{'associated_metaclass'}); - - $self; -}); - # pretend the add_method never happenned. it hasn't yet affected anything undef Class::MOP::Instance->meta->{_package_cache_flag}; @@ -733,12 +624,9 @@ undef Class::MOP::Instance->meta->{_package_cache_flag}; # no actual benefits. $_->meta->make_immutable( - ( $_->can("_new") ? ( - inline_constructor => 1, - constructor_name => "_new", - ) : ( - inline_constructor => 0, - ) ), + inline_constructor => 1, + replace_constructor => 1, + constructor_name => "_new", inline_accessors => 0, ) for qw/ Class::MOP::Package