mget/mset support for Hash
Yuval Kogman [Mon, 31 Dec 2007 10:44:07 +0000 (10:44 +0000)]
lib/MooseX/AttributeHelpers/MethodProvider/Hash.pm
lib/MooseX/AttributeHelpers/MethodProvider/ImmutableHash.pm
t/003_basic_hash.t

index f70c5ef..a477786 100644 (file)
@@ -11,13 +11,41 @@ sub set : method {
     if ($attr->has_type_constraint && $attr->type_constraint->isa('Moose::Meta::TypeConstraint::Parameterized')) {
         my $container_type_constraint = $attr->type_constraint->type_parameter;
         return sub { 
-            ($container_type_constraint->check($_[2])) 
-                || confess "Value " . ($_[2]||'undef') . " did not pass container type constraint";                        
-            $reader->($_[0])->{$_[1]} = $_[2] 
+            my ( $self, @kvp ) = @_;
+           
+            my ( @keys, @values );
+
+            while ( @kvp ) {
+                my ( $key, $value ) = ( shift(@kvp), shift(@kvp) );
+                ($container_type_constraint->check($value)) 
+                    || confess "Value " . ($value||'undef') . " did not pass container type constraint";
+                push @keys, $key;
+                push @values, $value;
+            }
+
+            if ( @values > 1 ) {
+                @{ $reader->($self) }{@keys} = @values;
+            } else {
+                $reader->($self)->{$keys[0]} = $values[0];
+            }
         };
     }
     else {
-        return sub { $reader->($_[0])->{$_[1]} = $_[2] };
+        return sub {
+            if ( @_ == 3 ) {
+                $reader->($_[0])->{$_[1]} = $_[2]
+            } else {
+                my ( $self, @kvp ) = @_;
+                my ( @keys, @values );
+
+                while ( @kvp ) {
+                    push @keys, shift @kvp;
+                    push @values, shift @kvp;
+                }
+
+                @{ $reader->($_[0]) }{@keys} = {@values};
+            }
+        };
     }
 }
 
index ea96a19..67f75bb 100644 (file)
@@ -11,7 +11,14 @@ sub exists : method {
 
 sub get : method {
     my ($attr, $reader, $writer) = @_;    
-    return sub { $reader->($_[0])->{$_[1]} };
+    return sub {
+        if ( @_ == 2 ) {
+            $reader->($_[0])->{$_[1]}
+        } else {
+            my ( $self, @keys ) = @_;
+            @{ $reader->($self) }{@keys}
+        }
+    };
 }
 
 sub keys : method {
index c0b3a2a..24a6b3f 100644 (file)
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 26;
+use Test::More tests => 32;
 use Test::Exception;
 
 BEGIN {
@@ -65,10 +65,27 @@ is_deeply($stuff->options, { foo => 'bar', bar => 'baz' }, '... got more options
 
 is($stuff->get_option('foo'), 'bar', '... got the right option');
 
+is_deeply([ $stuff->get_option(qw(foo bar)) ], [qw(bar baz)], "get multiple options at once");
+
+lives_ok {
+    $stuff->set_option(oink => "blah", xxy => "flop");
+} '... set the option okay';
+
+is($stuff->num_options, 4, "4 options");
+is_deeply([ $stuff->get_option(qw(foo bar oink xxy)) ], [qw(bar baz blah flop)], "get multiple options at once");
+
 lives_ok {
     $stuff->delete_option('bar');
 } '... deleted the option okay';
 
+lives_ok {
+    $stuff->delete_option('oink');
+} '... deleted the option okay';
+
+lives_ok {
+    $stuff->delete_option('xxy');
+} '... deleted the option okay';
+
 is($stuff->num_options, 1, '... we have 1 option(s)');
 is_deeply($stuff->options, { foo => 'bar' }, '... got more options now');