From: Yuval Kogman Date: Mon, 31 Dec 2007 10:44:07 +0000 (+0000) Subject: mget/mset support for Hash X-Git-Tag: 0.18_01~50 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=05f7da43b612f6c35c40227fa84a0a970c442ab1;p=gitmo%2FMooseX-AttributeHelpers.git mget/mset support for Hash --- diff --git a/lib/MooseX/AttributeHelpers/MethodProvider/Hash.pm b/lib/MooseX/AttributeHelpers/MethodProvider/Hash.pm index f70c5ef..a477786 100644 --- a/lib/MooseX/AttributeHelpers/MethodProvider/Hash.pm +++ b/lib/MooseX/AttributeHelpers/MethodProvider/Hash.pm @@ -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}; + } + }; } } diff --git a/lib/MooseX/AttributeHelpers/MethodProvider/ImmutableHash.pm b/lib/MooseX/AttributeHelpers/MethodProvider/ImmutableHash.pm index ea96a19..67f75bb 100644 --- a/lib/MooseX/AttributeHelpers/MethodProvider/ImmutableHash.pm +++ b/lib/MooseX/AttributeHelpers/MethodProvider/ImmutableHash.pm @@ -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 { diff --git a/t/003_basic_hash.t b/t/003_basic_hash.t index c0b3a2a..24a6b3f 100644 --- a/t/003_basic_hash.t +++ b/t/003_basic_hash.t @@ -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');