Add support for an "around" trigger in the setter
Shawn M Moore [Wed, 16 Jul 2008 05:45:25 +0000 (05:45 +0000)]
lib/Mouse/Meta/Attribute.pm
t/016-trigger.t

index 1c46633..4bdb9f8 100644 (file)
@@ -76,17 +76,28 @@ sub generate_accessor {
             $accessor .= '$before->($self, $_, $attribute);';
         }
 
-        if ($constraint) {
-            $accessor .= 'do {
-                my $display = defined($_) ? overload::StrVal($_) : "undef";
-                Carp::confess("Attribute ($name) does not pass the type constraint because: Validation failed for \'$type\' failed with value $display") unless $constraint->();
-            };'
+        if ($around) {
+            $accessor .= '$around->(sub {
+                my $self = shift;
+                $_ = $_[0];
+            ';
         }
 
-        $accessor .= '$self->{$key} = $_;';
+            if ($constraint) {
+                $accessor .= 'do {
+                    my $display = defined($_) ? overload::StrVal($_) : "undef";
+                    Carp::confess("Attribute ($name) does not pass the type constraint because: Validation failed for \'$type\' failed with value $display") unless $constraint->();
+                };'
+            }
 
-        if ($attribute->is_weak_ref) {
-            $accessor .= 'Scalar::Util::weaken($self->{$key}) if ref($self->{$key});';
+            $accessor .= '$self->{$key} = $_;';
+
+            if ($attribute->is_weak_ref) {
+                $accessor .= 'Scalar::Util::weaken($self->{$key}) if ref($self->{$key});';
+            }
+
+        if ($around) {
+            $accessor .= '}, $self, $_, $attribute);';
         }
 
         if ($after) {
index 4ba0743..61f79f0 100644 (file)
@@ -66,9 +66,11 @@ do {
             },
             around => sub {
                 my $code = shift;
-                push @trigger, ['around-before', @_];
-                $code->();
-                push @trigger, ['around-after', @_];
+                my ($self, $value, $attr) = @_;
+
+                push @trigger, ['around-before', $self, $value, $attr];
+                $code->($self, 4 * $value, $attr);
+                push @trigger, ['around-after', $self, $value, $attr];
             },
         },
     );
@@ -80,9 +82,11 @@ is(@trigger, 0, "trigger not called on constructor with default");
 is($o2->attr, 10, "reader");
 is(@trigger, 0, "trigger not called on reader");
 
-is($o2->attr(5), 5, "writer");
+is($o2->attr(5), 20, "writer");
 is_deeply([splice @trigger], [
-    ['before', $o2, 5, $o2->meta->get_attribute('attr')],
-    ['after',  $o2, 5, $o2->meta->get_attribute('attr')],
+    ['before',        $o2,  5, $o2->meta->get_attribute('attr')],
+    ['around-before', $o2,  5, $o2->meta->get_attribute('attr')],
+    ['around-after',  $o2,  5, $o2->meta->get_attribute('attr')],
+    ['after',         $o2, 20, $o2->meta->get_attribute('attr')],
 ]);