From: Matt S Trout Date: Wed, 3 Oct 2012 16:26:33 +0000 (+0000) Subject: has [ ... ] patch from tobyink X-Git-Tag: v1.000004~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1d17c7c12c2283c4daae3a9439a0aa629e743d73;p=gitmo%2FMoo.git has [ ... ] patch from tobyink --- diff --git a/Changes b/Changes index a9488d7..b60e085 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,5 @@ + - allow 'has \@attributes' like Moose does + 1.000003 - 2012-08-09 - make setter for weak_ref attributes return the value diff --git a/lib/Moo.pm b/lib/Moo.pm index 7148502..c3788d9 100644 --- a/lib/Moo.pm +++ b/lib/Moo.pm @@ -35,12 +35,18 @@ sub import { $class->_maybe_reset_handlemoose($target); }; _install_tracked $target => has => sub { - my ($name, %spec) = @_; - $class->_constructor_maker_for($target) - ->register_attribute_specs($name, \%spec); - $class->_accessor_maker_for($target) - ->generate_method($target, $name, \%spec); - $class->_maybe_reset_handlemoose($target); + my ($name_proto, %spec) = @_; + my $name_isref = ref $name_proto eq 'ARRAY'; + foreach my $name ($name_isref ? @$name_proto : $name_proto) { + # Note that when $name_proto is an arrayref, each attribute + # needs a separate \%specs hashref + my $spec_ref = $name_isref ? +{%spec} : \%spec; + $class->_constructor_maker_for($target) + ->register_attribute_specs($name, $spec_ref); + $class->_accessor_maker_for($target) + ->generate_method($target, $name, $spec_ref); + $class->_maybe_reset_handlemoose($target); + } return; }; foreach my $type (qw(before after around)) { @@ -790,6 +796,8 @@ Mithaldu - Christian Walde (cpan:MITHALDU) ilmari - Dagfinn Ilmari Mannsåker (cpan:ILMARI) +tobyink - Toby Inkster (cpan:TOBYINK) + =head1 COPYRIGHT Copyright (c) 2010-2011 the Moo L and L diff --git a/lib/Moo/Role.pm b/lib/Moo/Role.pm index 628258d..c382dd1 100644 --- a/lib/Moo/Role.pm +++ b/lib/Moo/Role.pm @@ -25,13 +25,17 @@ sub import { # get symbol table reference my $stash = do { no strict 'refs'; \%{"${target}::"} }; _install_tracked $target => has => sub { - my ($name, %spec) = @_; - ($INFO{$target}{accessor_maker} ||= do { - require Method::Generate::Accessor; - Method::Generate::Accessor->new - })->generate_method($target, $name, \%spec); - push @{$INFO{$target}{attributes}||=[]}, $name, \%spec; - $me->_maybe_reset_handlemoose($target); + my ($name_proto, %spec) = @_; + my $name_isref = ref $name_proto eq 'ARRAY'; + foreach my $name ($name_isref ? @$name_proto : $name_proto) { + my $spec_ref = $name_isref ? +{%spec} : \%spec; + ($INFO{$target}{accessor_maker} ||= do { + require Method::Generate::Accessor; + Method::Generate::Accessor->new + })->generate_method($target, $name, $spec_ref); + push @{$INFO{$target}{attributes}||=[]}, $name, $spec_ref; + $me->_maybe_reset_handlemoose($target); + } }; # install before/after/around subs foreach my $type (qw(before after around)) { diff --git a/t/has-array.t b/t/has-array.t new file mode 100644 index 0000000..3d2d91f --- /dev/null +++ b/t/has-array.t @@ -0,0 +1,30 @@ +use Test::More tests => 4; + +ok(eval { + package Local::Test::Role1; + use Moo::Role; + has [qw/ attr1 attr2 /] => (is => 'ro'); + 1; +}, 'has \@attrs works in roles') + or diag "EVAL FAILED: $@"; + +ok eval { + package Local::Test::Class1; + use Moo; + with 'Local::Test::Role1'; + has [qw/ attr3 attr4 /] => (is => 'ro'); + 1; +}, 'has \@attrs works in classes' + or diag "EVAL FAILED: $@"; + +my $obj = new_ok 'Local::Test::Class1' => [ + attr1 => 1, + attr2 => 2, + attr3 => 3, + attr4 => 4, +]; + +can_ok( + $obj, + qw( attr1 attr2 attr3 attr4 ), +);