From: Shawn M Moore Date: Thu, 14 May 2009 04:47:17 +0000 (-0400) Subject: Add accessor helper X-Git-Tag: 0.18_01~8^2~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=57e529ffde091da5b89eec91cce81ecf68501737;p=gitmo%2FMooseX-AttributeHelpers.git Add accessor helper --- diff --git a/lib/MooseX/AttributeHelpers/MethodProvider/Array.pm b/lib/MooseX/AttributeHelpers/MethodProvider/Array.pm index 3fead0c..400c46e 100644 --- a/lib/MooseX/AttributeHelpers/MethodProvider/Array.pm +++ b/lib/MooseX/AttributeHelpers/MethodProvider/Array.pm @@ -86,6 +86,44 @@ sub set : method { } } +sub accessor : method { + my ($attr, $reader, $writer) = @_; + + if ($attr->has_type_constraint && $attr->type_constraint->isa('Moose::Meta::TypeConstraint::Parameterized')) { + my $container_type_constraint = $attr->type_constraint->type_parameter; + return sub { + my $self = shift; + + if (@_ == 1) { # reader + return $reader->($self)->[$_[0]]; + } + elsif (@_ == 2) { # writer + ($container_type_constraint->check($_[1])) + || confess "Value " . ($_[1]||'undef') . " did not pass container type constraint"; + $reader->($self)->[$_[0]] = $_[1]; + } + else { + confess "One or two arguments expected, not " . @_; + } + }; + } + else { + return sub { + my $self = shift; + + if (@_ == 1) { # reader + return $reader->($self)->[$_[0]]; + } + elsif (@_ == 2) { # writer + $reader->($self)->[$_[0]] = $_[1]; + } + else { + confess "One or two arguments expected, not " . @_; + } + }; + } +} + sub clear : method { my ($attr, $reader, $writer) = @_; return sub { @@ -214,6 +252,11 @@ You can provide an optional subroutine reference to sort with (as you can with the core C function). However, instead of using C<$a> and C<$b>, you will need to use C<$_[0]> and C<$_[1]> instead. +=item B + +If passed one argument, returns the value of the requested element. +If passed two arguments, sets the value of the requested element. + =back =head1 BUGS diff --git a/t/002_basic_array.t b/t/002_basic_array.t index 9ac81f2..a336276 100644 --- a/t/002_basic_array.t +++ b/t/002_basic_array.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 64; +use Test::More tests => 69; use Test::Exception; BEGIN { @@ -31,6 +31,7 @@ BEGIN { 'clear' => 'clear_options', 'splice' => 'splice_options', 'sort_in_place' => 'sort_options_in_place', + 'accessor' => 'option_accessor', }, curries => { 'push' => { @@ -59,6 +60,7 @@ can_ok($stuff, $_) for qw[ clear_options has_options sort_options_in_place + option_accessor ]; is_deeply($stuff->options, [10, 12], '... got options'); @@ -172,6 +174,8 @@ is_deeply( 'splice added expected option' ); +is($stuff->option_accessor(1 => 'foo++'), 'foo++'); +is($stuff->option_accessor(1), 'foo++'); ## check some errors @@ -207,6 +211,16 @@ dies_ok { $stuff->sort_in_place_options( undef ); } '... sort rejects arg of invalid type'; +dies_ok { + my $stuff = Stuff->new(); + $stuff->option_accessor(); +} '... accessor rejects 0 args'; + +dies_ok { + my $stuff = Stuff->new(); + $stuff->option_accessor(1, 2, 3); +} '... accessor rejects 3 args'; + ## test the meta my $options = $stuff->meta->get_attribute('options'); @@ -224,6 +238,7 @@ is_deeply($options->provides, { 'clear' => 'clear_options', 'splice' => 'splice_options', 'sort_in_place' => 'sort_options_in_place', + 'accessor' => 'option_accessor', }, '... got the right provides mapping'); is($options->type_constraint->type_parameter, 'Str', '... got the right container type');