Remove p6 style attribute naming
[gitmo/Class-MOP.git] / lib / Class / MOP.pm
index 29bd467..bd51287 100644 (file)
@@ -16,7 +16,8 @@ use Class::MOP::Method;
 use Class::MOP::Immutable;
 
 BEGIN {
-    our $VERSION   = '0.56';
+    
+    our $VERSION   = '0.65';
     our $AUTHORITY = 'cpan:STEVAN';    
     
     *IS_RUNNING_ON_5_10 = ($] < 5.009_005) 
@@ -34,14 +35,9 @@ BEGIN {
         
     # stash these for a sec, and see how things go
     my $_PP_subname       = sub { $_[1] };
-    my $_PP_get_code_info = sub ($) { 
-        return (            
-            Sub::Identify::stash_name($_[0]), 
-            Sub::Identify::sub_name($_[0])
-        ) 
-    };    
+    my $_PP_get_code_info = \&Sub::Identify::get_code_info;    
     
-    if ($ENV{CLASS_MOP_NO_XS} == 1) {
+    if ($ENV{CLASS_MOP_NO_XS}) {
         # NOTE:
         # this is if you really want things
         # to be slow, then you can force the
@@ -50,8 +46,21 @@ BEGIN {
         # the XS as possible.
         # - SL
         no warnings 'prototype', 'redefine';
-        # get this from MRO::Compat ...
-        *check_package_cache_flag = \&MRO::Compat::__get_pkg_gen_pp;
+        
+        unless (IS_RUNNING_ON_5_10()) {
+            # get this from MRO::Compat ...
+            *check_package_cache_flag = \&MRO::Compat::__get_pkg_gen_pp;
+        }
+        else {
+            # NOTE:
+            # but if we are running 5.10 
+            # there is no need to use the 
+            # Pure Perl version since we 
+            # can use the built in mro 
+            # version instead.
+            # - SL
+            *check_package_cache_flag = \&mro::get_pkg_gen; 
+        }
         # our own version of Sub::Name
         *subname       = $_PP_subname;
         # and the Sub::Identify version of the get_code_info
@@ -81,10 +90,7 @@ BEGIN {
         # for naming our CVs, if not, we 
         # use the workaround instead.
         if ( eval { require Sub::Name } ) {
-            *subname = sub {
-                #warn "Class::MOP::subname called with @_";
-                Sub::Name::subname(@_);
-            };
+            *subname = \&Sub::Name::subname;
         } 
         else {
             *subname = $_PP_subname;
@@ -119,29 +125,65 @@ BEGIN {
 
 sub load_class {
     my $class = shift;
-    # see if this is already
-    # loaded in the symbol table
-    return 1 if is_class_loaded($class);
-    # otherwise require it ...
-    my $file = $class . '.pm';
-    $file =~ s{::}{/}g;
-    eval { CORE::require($file) };
-    confess "Could not load class ($class) because : $@" if $@;
+
+    if (ref($class) || !defined($class) || !length($class)) {
+        my $display = defined($class) ? $class : 'undef';
+        confess "Invalid class name ($display)";
+    }
+
+    # 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;
+        eval { CORE::require($file) };
+        confess "Could not load class ($class) because : $@" if $@;
+    }
+
+    # initialize a metaclass if necessary
     unless (does_metaclass_exist($class)) {
         eval { Class::MOP::Class->initialize($class) };
         confess "Could not initialize class ($class) because : $@" if $@;
     }
-    1; # return true if it worked
+
+    return get_metaclass_by_name($class);
 }
 
 sub is_class_loaded {
     my $class = shift;
-    no strict 'refs';
-    return 1 if defined ${"${class}::VERSION"} || defined @{"${class}::ISA"};
-    foreach my $symbol (keys %{"${class}::"}) {
-            next if substr($symbol, -2, 2) eq '::';
-            return 1 if defined &{"${class}::${symbol}"};
+
+    return 0 if ref($class) || !defined($class) || !length($class);
+
+    # walk the symbol table tree to avoid autovififying
+    # \*{${main::}{"Foo::"}} == \*main::Foo::
+
+    my $pack = \*::;
+    foreach my $part (split('::', $class)) {
+        return 0 unless exists ${$$pack}{"${part}::"};
+        $pack = \*{${$$pack}{"${part}::"}};
     }
+
+    # check for $VERSION or @ISA
+    return 1 if exists ${$$pack}{VERSION}
+             && defined *{${$$pack}{VERSION}}{SCALAR};
+    return 1 if exists ${$$pack}{ISA}
+             && defined *{${$$pack}{ISA}}{ARRAY};
+
+    # check for any method
+    foreach ( keys %{$$pack} ) {
+        next if substr($_, -2, 2) eq '::';
+
+        my $glob = ${$$pack}{$_} || next;
+
+        # constant subs
+        if ( IS_RUNNING_ON_5_10 ) {
+            return 1 if ref $glob eq 'SCALAR';
+        }
+
+        return 1 if defined *{$glob}{CODE};
+    }
+
+    # fail
     return 0;
 }
 
@@ -174,7 +216,7 @@ sub is_class_loaded {
 ## Class::MOP::Package
 
 Class::MOP::Package->meta->add_attribute(
-    Class::MOP::Attribute->new('$!package' => (
+    Class::MOP::Attribute->new('package' => (
         reader   => {
             # NOTE: we need to do this in order
             # for the instance meta-object to
@@ -189,7 +231,7 @@ Class::MOP::Package->meta->add_attribute(
 );
 
 Class::MOP::Package->meta->add_attribute(
-    Class::MOP::Attribute->new('%!namespace' => (
+    Class::MOP::Attribute->new('namespace' => (
         reader => {
             # NOTE:
             # we just alias the original method
@@ -224,7 +266,7 @@ Class::MOP::Package->meta->add_method('initialize' => sub {
 # the metaclass, isn't abstraction great :)
 
 Class::MOP::Module->meta->add_attribute(
-    Class::MOP::Attribute->new('$!version' => (
+    Class::MOP::Attribute->new('version' => (
         reader => {
             # NOTE:
             # we just alias the original method
@@ -243,7 +285,7 @@ Class::MOP::Module->meta->add_attribute(
 # well.
 
 Class::MOP::Module->meta->add_attribute(
-    Class::MOP::Attribute->new('$!authority' => (
+    Class::MOP::Attribute->new('authority' => (
         reader => {
             # NOTE:
             # we just alias the original method
@@ -259,7 +301,7 @@ Class::MOP::Module->meta->add_attribute(
 ## Class::MOP::Class
 
 Class::MOP::Class->meta->add_attribute(
-    Class::MOP::Attribute->new('%!attributes' => (
+    Class::MOP::Attribute->new('attributes' => (
         reader   => {
             # NOTE: we need to do this in order
             # for the instance meta-object to
@@ -275,7 +317,7 @@ Class::MOP::Class->meta->add_attribute(
 );
 
 Class::MOP::Class->meta->add_attribute(
-    Class::MOP::Attribute->new('%!methods' => (
+    Class::MOP::Attribute->new('methods' => (
         init_arg => 'methods',
         reader   => {
             # NOTE:
@@ -288,7 +330,7 @@ Class::MOP::Class->meta->add_attribute(
 );
 
 Class::MOP::Class->meta->add_attribute(
-    Class::MOP::Attribute->new('@!superclasses' => (
+    Class::MOP::Attribute->new('superclasses' => (
         accessor => {
             # NOTE:
             # we just alias the original method
@@ -301,7 +343,7 @@ Class::MOP::Class->meta->add_attribute(
 );
 
 Class::MOP::Class->meta->add_attribute(
-    Class::MOP::Attribute->new('$!attribute_metaclass' => (
+    Class::MOP::Attribute->new('attribute_metaclass' => (
         reader   => {
             # NOTE:
             # we just alias the original method
@@ -314,7 +356,7 @@ Class::MOP::Class->meta->add_attribute(
 );
 
 Class::MOP::Class->meta->add_attribute(
-    Class::MOP::Attribute->new('$!method_metaclass' => (
+    Class::MOP::Attribute->new('method_metaclass' => (
         reader   => {
             # NOTE:
             # we just alias the original method
@@ -327,7 +369,7 @@ Class::MOP::Class->meta->add_attribute(
 );
 
 Class::MOP::Class->meta->add_attribute(
-    Class::MOP::Attribute->new('$!instance_metaclass' => (
+    Class::MOP::Attribute->new('instance_metaclass' => (
         reader   => {
             # NOTE: we need to do this in order
             # for the instance meta-object to
@@ -352,7 +394,7 @@ Class::MOP::Class->meta->add_attribute(
 ## Class::MOP::Attribute
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!name' => (
+    Class::MOP::Attribute->new('name' => (
         init_arg => 'name',
         reader   => {
             # NOTE: we need to do this in order
@@ -367,7 +409,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!associated_class' => (
+    Class::MOP::Attribute->new('associated_class' => (
         init_arg => 'associated_class',
         reader   => {
             # NOTE: we need to do this in order
@@ -382,7 +424,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!accessor' => (
+    Class::MOP::Attribute->new('accessor' => (
         init_arg  => 'accessor',
         reader    => { 'accessor'     => \&Class::MOP::Attribute::accessor     },
         predicate => { 'has_accessor' => \&Class::MOP::Attribute::has_accessor },
@@ -390,7 +432,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!reader' => (
+    Class::MOP::Attribute->new('reader' => (
         init_arg  => 'reader',
         reader    => { 'reader'     => \&Class::MOP::Attribute::reader     },
         predicate => { 'has_reader' => \&Class::MOP::Attribute::has_reader },
@@ -398,7 +440,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!initializer' => (
+    Class::MOP::Attribute->new('initializer' => (
         init_arg  => 'initializer',
         reader    => { 'initializer'     => \&Class::MOP::Attribute::initializer     },
         predicate => { 'has_initializer' => \&Class::MOP::Attribute::has_initializer },
@@ -406,7 +448,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!writer' => (
+    Class::MOP::Attribute->new('writer' => (
         init_arg  => 'writer',
         reader    => { 'writer'     => \&Class::MOP::Attribute::writer     },
         predicate => { 'has_writer' => \&Class::MOP::Attribute::has_writer },
@@ -414,7 +456,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!predicate' => (
+    Class::MOP::Attribute->new('predicate' => (
         init_arg  => 'predicate',
         reader    => { 'predicate'     => \&Class::MOP::Attribute::predicate     },
         predicate => { 'has_predicate' => \&Class::MOP::Attribute::has_predicate },
@@ -422,7 +464,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!clearer' => (
+    Class::MOP::Attribute->new('clearer' => (
         init_arg  => 'clearer',
         reader    => { 'clearer'     => \&Class::MOP::Attribute::clearer     },
         predicate => { 'has_clearer' => \&Class::MOP::Attribute::has_clearer },
@@ -430,7 +472,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!builder' => (
+    Class::MOP::Attribute->new('builder' => (
         init_arg  => 'builder',
         reader    => { 'builder'     => \&Class::MOP::Attribute::builder     },
         predicate => { 'has_builder' => \&Class::MOP::Attribute::has_builder },
@@ -438,7 +480,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!init_arg' => (
+    Class::MOP::Attribute->new('init_arg' => (
         init_arg  => 'init_arg',
         reader    => { 'init_arg'     => \&Class::MOP::Attribute::init_arg     },
         predicate => { 'has_init_arg' => \&Class::MOP::Attribute::has_init_arg },
@@ -446,7 +488,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('$!default' => (
+    Class::MOP::Attribute->new('default' => (
         init_arg  => 'default',
         # default has a custom 'reader' method ...
         predicate => { 'has_default' => \&Class::MOP::Attribute::has_default },
@@ -454,7 +496,7 @@ Class::MOP::Attribute->meta->add_attribute(
 );
 
 Class::MOP::Attribute->meta->add_attribute(
-    Class::MOP::Attribute->new('@!associated_methods' => (
+    Class::MOP::Attribute->new('associated_methods' => (
         init_arg => 'associated_methods',
         reader   => { 'associated_methods' => \&Class::MOP::Attribute::associated_methods },
         default  => sub { [] }
@@ -487,6 +529,7 @@ Class::MOP::Attribute->meta->add_method('new' => sub {
                        "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(name => $name, %options);
 });
@@ -498,23 +541,22 @@ Class::MOP::Attribute->meta->add_method('clone' => sub {
 
 ## --------------------------------------------------------
 ## Class::MOP::Method
-
 Class::MOP::Method->meta->add_attribute(
-    Class::MOP::Attribute->new('&!body' => (
+    Class::MOP::Attribute->new('body' => (
         init_arg => 'body',
         reader   => { 'body' => \&Class::MOP::Method::body },
     ))
 );
 
 Class::MOP::Method->meta->add_attribute(
-    Class::MOP::Attribute->new('$!package_name' => (
+    Class::MOP::Attribute->new('package_name' => (
         init_arg => 'package_name',
         reader   => { 'package_name' => \&Class::MOP::Method::package_name },
     ))
 );
 
 Class::MOP::Method->meta->add_attribute(
-    Class::MOP::Attribute->new('$!name' => (
+    Class::MOP::Attribute->new('name' => (
         init_arg => 'name',
         reader   => { 'name' => \&Class::MOP::Method::name },
     ))
@@ -525,7 +567,7 @@ Class::MOP::Method->meta->add_method('wrap' => sub {
     my $code    = shift;
     my %options = @_;
 
-    ('CODE' eq (Scalar::Util::reftype($code) || ''))
+    ('CODE' eq ref($code))
         || confess "You must supply a CODE reference to bless, not (" . ($code || 'undef') . ")";
 
     ($options{package_name} && $options{name})
@@ -549,14 +591,14 @@ Class::MOP::Method->meta->add_method('clone' => sub {
 # practices of attributes, but we put
 # it here for completeness
 Class::MOP::Method::Wrapped->meta->add_attribute(
-    Class::MOP::Attribute->new('%!modifier_table')
+    Class::MOP::Attribute->new('modifier_table')
 );
 
 ## --------------------------------------------------------
 ## Class::MOP::Method::Generated
 
 Class::MOP::Method::Generated->meta->add_attribute(
-    Class::MOP::Attribute->new('$!is_inline' => (
+    Class::MOP::Attribute->new('is_inline' => (
         init_arg => 'is_inline',
         reader   => { 'is_inline' => \&Class::MOP::Method::Generated::is_inline },
         default  => 0, 
@@ -576,7 +618,7 @@ Class::MOP::Method::Generated->meta->add_method('new' => sub {
 ## Class::MOP::Method::Accessor
 
 Class::MOP::Method::Accessor->meta->add_attribute(
-    Class::MOP::Attribute->new('$!attribute' => (
+    Class::MOP::Attribute->new('attribute' => (
         init_arg => 'attribute',
         reader   => {
             'associated_attribute' => \&Class::MOP::Method::Accessor::associated_attribute
@@ -585,7 +627,7 @@ Class::MOP::Method::Accessor->meta->add_attribute(
 );
 
 Class::MOP::Method::Accessor->meta->add_attribute(
-    Class::MOP::Attribute->new('$!accessor_type' => (
+    Class::MOP::Attribute->new('accessor_type' => (
         init_arg => 'accessor_type',
         reader   => { 'accessor_type' => \&Class::MOP::Method::Accessor::accessor_type },
     ))
@@ -613,7 +655,7 @@ Class::MOP::Method::Accessor->meta->add_method('new' => sub {
     # we don't want this creating
     # a cycle in the code, if not
     # needed
-    Scalar::Util::weaken($self->{'$!attribute'});
+    Scalar::Util::weaken($self->{'attribute'});
 
     $self->initialize_body;  
     
@@ -625,7 +667,7 @@ Class::MOP::Method::Accessor->meta->add_method('new' => sub {
 ## Class::MOP::Method::Constructor
 
 Class::MOP::Method::Constructor->meta->add_attribute(
-    Class::MOP::Attribute->new('%!options' => (
+    Class::MOP::Attribute->new('options' => (
         init_arg => 'options',
         reader   => {
             'options' => \&Class::MOP::Method::Constructor::options
@@ -635,7 +677,7 @@ Class::MOP::Method::Constructor->meta->add_attribute(
 );
 
 Class::MOP::Method::Constructor->meta->add_attribute(
-    Class::MOP::Attribute->new('$!associated_metaclass' => (
+    Class::MOP::Attribute->new('associated_metaclass' => (
         init_arg => 'metaclass',
         reader   => {
             'associated_metaclass' => \&Class::MOP::Method::Constructor::associated_metaclass
@@ -660,7 +702,7 @@ Class::MOP::Method::Constructor->meta->add_method('new' => sub {
     # we don't want this creating
     # a cycle in the code, if not
     # needed
-    Scalar::Util::weaken($self->{'$!associated_metaclass'});
+    Scalar::Util::weaken($self->{'associated_metaclass'});
 
     $self->initialize_body;  
     
@@ -675,11 +717,11 @@ Class::MOP::Method::Constructor->meta->add_method('new' => sub {
 # included for completeness
 
 Class::MOP::Instance->meta->add_attribute(
-    Class::MOP::Attribute->new('$!meta')
+    Class::MOP::Attribute->new('meta')
 );
 
 Class::MOP::Instance->meta->add_attribute(
-    Class::MOP::Attribute->new('@!slots')
+    Class::MOP::Attribute->new('slots')
 );
 
 ## --------------------------------------------------------