immutable constructor for Attribute
Yuval Kogman [Wed, 13 Aug 2008 21:19:38 +0000 (21:19 +0000)]
lib/Class/MOP.pm
lib/Class/MOP/Attribute.pm
t/014_attribute_introspection.t

index 65df897..05291ae 100644 (file)
@@ -451,40 +451,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, @_);
index 496050d..d7df895 100644 (file)
@@ -51,10 +51,16 @@ sub new {
         confess("A required attribute must have either 'init_arg', 'builder', or 'default'");
     }
 
+    $class->_new(%options);
+}
+
+sub _new {
+    my ( $class, %options ) = @_;
+
     bless {
-        'name'      => $name,
-        'accessor'  => $options{accessor},
-        'reader'    => $options{reader},
+        'name'        => $options{name},
+        'accessor'    => $options{accessor},
+        'reader'      => $options{reader},
         'writer'      => $options{writer},
         'predicate'   => $options{predicate},
         'clearer'     => $options{clearer},
index dc1e18c..f9c8bb1 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 62;
+use Test::More tests => 63;
 use Test::Exception;
 
 BEGIN {
@@ -58,6 +58,8 @@ BEGIN {
         process_accessors
         install_accessors
         remove_accessors
+
+        _new
         );
 
     is_deeply(