remove multi-populate code to fix exists/defined new() bug
[gitmo/Moo.git] / lib / Method / Generate / Accessor.pm
index d315818..fe268ba 100644 (file)
@@ -17,6 +17,7 @@ BEGIN {
 
 sub generate_method {
   my ($self, $into, $name, $spec, $quote_opts) = @_;
+  $name =~ s/^\+//;
   die "Must have an is" unless my $is = $spec->{is};
   if ($is eq 'ro') {
     $spec->{reader} = $name unless exists $spec->{reader};
@@ -42,6 +43,18 @@ sub generate_method {
   if (($spec->{trigger}||0) eq 1) {
     $spec->{trigger} = quote_sub('shift->_trigger_'.$name.'(@_)');
   }
+  if (exists $spec->{default}) {
+    my $default = $spec->{default};
+    unless (ref $default) {
+      die "Invalid default $default";
+    }
+    if (ref $default ne 'CODE') {
+      unless (eval { \&$default }) {
+        die "Invalid default $default";
+      }
+    }
+  }
+
   my %methods;
   if (my $reader = $spec->{reader}) {
     if (our $CAN_HAZ_XS && $self->is_simple_get($name, $spec)) {
@@ -385,11 +398,6 @@ sub _generate_populate_set {
   }
 }
 
-sub generate_multi_set {
-  my ($self, $me, $to_set, $from) = @_;
-  "\@{${me}}{qw(${\join ' ', @$to_set})} = $from";
-}
-
 sub _generate_core_set {
   my ($self, $me, $name, $spec, $value) = @_;
   my $name_str = perlstring $name;
@@ -399,9 +407,10 @@ sub _generate_core_set {
 sub _generate_simple_set {
   my ($self, $me, $name, $spec, $value) = @_;
   my $name_str = perlstring $name;
-  my $simple = $self->_generate_core_set($self, $me, $name, $spec, $value);
 
   if ($spec->{weak_ref}) {
+    $value = '$preserve = '.$value;
+    my $simple = $self->_generate_core_set($me, $name, $spec, $value);
     require Scalar::Util;
 
     # Perl < 5.8.3 can't weaken refs to readonly vars
@@ -413,8 +422,10 @@ sub _generate_simple_set {
     #
     # but requires XS and is just too damn crazy
     # so simply throw a better exception
-    Moo::_Utils::lt_5_8_3() ? <<"EOC" : "Scalar::Util::weaken(${simple})";
+    my $weak_simple = "my \$preserve; Scalar::Util::weaken(${simple})";
+    Moo::_Utils::lt_5_8_3() ? <<"EOC" : $weak_simple;
 
+      my \$preserve;
       eval { Scalar::Util::weaken($simple); 1 } or do {
         if( \$@ =~ /Modification of a read-only value attempted/) {
           require Carp;
@@ -428,7 +439,7 @@ sub _generate_simple_set {
       };
 EOC
   } else {
-    $simple;
+    $self->_generate_core_set($me, $name, $spec, $value);
   }
 }
 
@@ -457,7 +468,8 @@ sub _generate_xs {
   my ($self, $type, $into, $name, $slot) = @_;
   Class::XSAccessor->import(
     class => $into,
-    $type => { $name => $slot }
+    $type => { $name => $slot },
+    replace => 1,
   );
   $into->can($name);
 }