X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMooseX%2FAttributeHelpers%2FMethodProvider%2FArray.pm;h=2c4e27bbee6891cf4ac59f6c7c0af24a496889dd;hb=2e74144c8801485e5c33fdcdcbee9f7d882c1a3a;hp=d953c97c97cdd1bef555cc09ea3e9f443653a0ee;hpb=b9dc8e2f66cb0c06a8d52aaa3b4734237b749b20;p=gitmo%2FMooseX-AttributeHelpers.git diff --git a/lib/MooseX/AttributeHelpers/MethodProvider/Array.pm b/lib/MooseX/AttributeHelpers/MethodProvider/Array.pm index d953c97..2c4e27b 100644 --- a/lib/MooseX/AttributeHelpers/MethodProvider/Array.pm +++ b/lib/MooseX/AttributeHelpers/MethodProvider/Array.pm @@ -1,106 +1,196 @@ package MooseX::AttributeHelpers::MethodProvider::Array; use Moose::Role; +our $VERSION = '0.23'; +$VERSION = eval $VERSION; +our $AUTHORITY = 'cpan:STEVAN'; + +with 'MooseX::AttributeHelpers::MethodProvider::List'; + sub push : method { - my ($attr) = @_; - if ($attr->has_container_type) { - my $container_type_constraint = $attr->container_type_constraint; + 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 $instance = CORE::shift; $container_type_constraint->check($_) - || confess "Value " . ($_||'undef') . " did not pass container type constraint" + || confess "Value " . ($_||'undef') . " did not pass container type constraint '$container_type_constraint'" foreach @_; - CORE::push @{$attr->get_value($instance)} => @_; + CORE::push @{$reader->($instance)} => @_; }; } else { return sub { my $instance = CORE::shift; - CORE::push @{$attr->get_value($instance)} => @_; + CORE::push @{$reader->($instance)} => @_; }; } } sub pop : method { - my ($attr) = @_; + my ($attr, $reader, $writer) = @_; return sub { - CORE::pop @{$attr->get_value($_[0])} + CORE::pop @{$reader->($_[0])} }; } sub unshift : method { - my ($attr) = @_; - if ($attr->has_container_type) { - my $container_type_constraint = $attr->container_type_constraint; + 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 $instance = CORE::shift; $container_type_constraint->check($_) - || confess "Value " . ($_||'undef') . " did not pass container type constraint" + || confess "Value " . ($_||'undef') . " did not pass container type constraint '$container_type_constraint'" foreach @_; - CORE::unshift @{$attr->get_value($instance)} => @_; + CORE::unshift @{$reader->($instance)} => @_; }; } else { return sub { my $instance = CORE::shift; - CORE::unshift @{$attr->get_value($instance)} => @_; + CORE::unshift @{$reader->($instance)} => @_; }; } } sub shift : method { - my ($attr) = @_; + my ($attr, $reader, $writer) = @_; return sub { - CORE::shift @{$attr->get_value($_[0])} + CORE::shift @{$reader->($_[0])} }; } sub get : method { - my ($attr) = @_; + my ($attr, $reader, $writer) = @_; return sub { - $attr->get_value($_[0])->[$_[1]] + $reader->($_[0])->[$_[1]] }; } sub set : method { - my ($attr) = @_; - if ($attr->has_container_type) { - my $container_type_constraint = $attr->container_type_constraint; + 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 { ($container_type_constraint->check($_[2])) - || confess "Value " . ($_[2]||'undef') . " did not pass container type constraint"; - $attr->get_value($_[0])->[$_[1]] = $_[2] + || confess "Value " . ($_[2]||'undef') . " did not pass container type constraint '$container_type_constraint'"; + $reader->($_[0])->[$_[1]] = $_[2] }; } else { return sub { - $attr->get_value($_[0])->[$_[1]] = $_[2] + $reader->($_[0])->[$_[1]] = $_[2] }; } } - -sub count : method { - my ($attr) = @_; - return sub { - scalar @{$attr->get_value($_[0])} - }; + +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 '$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 empty : method { - my ($attr) = @_; +sub clear : method { + my ($attr, $reader, $writer) = @_; return sub { - scalar @{$attr->get_value($_[0])} ? 1 : 0 - }; + @{$reader->($_[0])} = () + }; +} + +sub delete : method { + my ($attr, $reader, $writer) = @_; + return sub { + CORE::splice @{$reader->($_[0])}, $_[1], 1; + } +} + +sub insert : 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 { + ($container_type_constraint->check($_[2])) + || confess "Value " . ($_[2]||'undef') . " did not pass container type constraint '$container_type_constraint'"; + CORE::splice @{$reader->($_[0])}, $_[1], 0, $_[2]; + }; + } + else { + return sub { + CORE::splice @{$reader->($_[0])}, $_[1], 0, $_[2]; + }; + } +} + +sub splice : 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, $i, $j, @elems ) = @_; + ($container_type_constraint->check($_)) + || confess "Value " . (defined($_) ? $_ : 'undef') . " did not pass container type constraint '$container_type_constraint'" for @elems; + CORE::splice @{$reader->($self)}, $i, $j, @elems; + }; + } + else { + return sub { + my ( $self, $i, $j, @elems ) = @_; + CORE::splice @{$reader->($self)}, $i, $j, @elems; + }; + } } -sub find : method { - my ($attr) = @_; +sub sort_in_place : method { + my ($attr, $reader, $writer) = @_; return sub { my ($instance, $predicate) = @_; - foreach my $val (@{$attr->get_value($instance)}) { - return $val if $predicate->($val); + + die "Argument must be a code reference" + if $predicate && ref $predicate ne 'CODE'; + + my @sorted; + if ($predicate) { + @sorted = CORE::sort { $predicate->($a, $b) } @{$reader->($instance)}; + } + else { + @sorted = CORE::sort @{$reader->($instance)}; } - return; + + $writer->($instance, \@sorted); }; } @@ -110,4 +200,82 @@ __END__ =pod +=head1 NAME + +MooseX::AttributeHelpers::MethodProvider::Array + +=head1 DESCRIPTION + +This is a role which provides the method generators for +L. + +=head1 METHODS + +=over 4 + +=item B + +=back + +=head1 PROVIDED METHODS + +This module also consumes the B method providers, to +see those provied methods, refer to that documentation. + +=over 4 + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +Sorts the array I, modifying the value of the attribute. + +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 + +All complex software has bugs lurking in it, and this module is no +exception. If you find a bug please either email me, or add the bug +to cpan-RT. + +=head1 AUTHOR + +Stevan Little Estevan@iinteractive.comE + +=head1 COPYRIGHT AND LICENSE + +Copyright 2007-2009 by Infinity Interactive, Inc. + +L + +This library is free software; you can redistribute it and/or modify +it under the same terms as Perl itself. + =cut