RT #83361, asserter now operates on definedness
Matt Phillips [Fri, 15 Feb 2013 20:14:10 +0000 (15:14 -0500)]
As per haargs suggestion:
11:32 <haarg> mattp: i'd say use the predicate to test for existance, but after
calling get.  so something like do { my $val = $get->(); die "Attempted to
access..." unless $has->(); $val; }

Changes
lib/Method/Generate/Accessor.pm
t/accessor-handles.t

diff --git a/Changes b/Changes
index fc4708f..789fe25 100644 (file)
--- a/Changes
+++ b/Changes
@@ -3,6 +3,7 @@
   - expand is => 'lazy' doc to make it clear that you can make rw lazy
     attributes if you really want to
   - handles => "RoleName" tries to load the module
+  - fix delegation to false/undef attributes (RT#83361)
 
 1.000008 - 2013-02-06
   - Re-export on 'use Moo' after 'no Moo'
index 1a13a56..3901043 100644 (file)
@@ -163,9 +163,17 @@ sub generate_method {
   }
   if (my $asserter = $spec->{asserter}) {
     $self->{captures} = {};
+
+    my $code = "do {\n"
+               ."  my \$val = ".$self->_generate_get($name, $spec).";\n"
+               ."  unless (".$self->_generate_simple_has('$_[0]', $name).") {\n"
+               .qq!    die "Attempted to access '${name}' but it is not set";\n!
+               ."  }\n"
+               ."  \$val;\n"
+               ."}\n";
+
     $methods{$asserter} =
-      quote_sub "${into}::${asserter}" =>
-        'do { '.$self->_generate_get($name, $spec).qq! }||die "Attempted to access '${name}' but it is not set"!,
+      quote_sub "${into}::${asserter}" => $code,
         delete $self->{captures}
       ;
   }
index a0df36c..b88a700 100644 (file)
@@ -7,6 +7,8 @@ use lib "t/lib";
   package Baz;
   use Moo;
   sub beep {'beep'}
+
+  sub is_passed_undefined { !defined($_[0]) ? 'bar' : 'fail' }
 }
 
 {
@@ -44,6 +46,13 @@ use lib "t/lib";
      eat_curry => [ yum => 'Curry!' ],
   });
   has foo5 => ( is => 'ro', handles => 'ExtRobot' );
+  has foo6 => ( is => 'rw',
+                handles => { foobot => '${\\Baz->can("beep")}'},
+                default => sub { 0 } );
+  has foo7 => ( is => 'rw',
+                handles => { foobar => '${\\Baz->can("is_passed_undefined")}'},
+                default => sub { undef } );
+
 }
 
 my $bar = Bar->new(
@@ -62,4 +71,7 @@ is $bar->beep, 'beep', 'handles loads roles';
 
 is $bar->eat_curry, 'Curry!', 'handles works for currying';
 
+is $bar->foobot, 'beep', 'asserter checks for existence not truth, on false value';
+
+is $bar->foobar, 'bar', 'asserter checks for existence not truth, on undef ';
 done_testing;