=pod =head1 NAME Moose::Cookbook::Snack::ArrayRef - Using the ArrayRef type constraint =head1 SYNOPSIS package Fruit; use Moose; has 'name' => (is => 'rw', required => 1); has 'species' => (is => 'rw', required => 1); package ProduceStore; use Moose; use Moose::Util::TypeConstraints; has 'fruit_aisle' => (isa => 'ArrayRef[Fruit]', is => 'rw'); package main; # we need something to put in the fruit aisle my $orange = Fruit->new(name => 'orange', species => 'C. sinensis'); my $apple = Fruit->new(name => 'apple', species => 'M. domestica'); my @fruit = ($apple, $orange); my $store = ProduceStore->new(fruit_aisle => \@fruit); =head1 DESCRIPTION The ArrayRef type constraint is used to store a reference to a Perl list or array variable as an attribute of a Moose object. =head2 Disclaimer The code in this document will work on Moose as advertised, but the developers strongly recommend using something like L or L when working with array references in order to help keep your Moose objects nice and encapsulated. =head2 Assigning arrays to an ArrayRef attribute Once a Moose-based object with an C attribute has been created, you can pass an array (by reference) to that object attribute using that attribute's accessor. This is how we assign the apple and orange to the store's C C attribute, we pass an array containing both objects by reference to the C attribute: my @fruit = ($apple, $orange); my $store = ProduceStore->new(fruit_aisle => \@fruit); Or you can pass an anonymous array to the C attribute as well. If you created two new objects, C<$grape> and C<$tomato>, and assigned them to the C, they would replace the apple and the orange in the store's fruit aisle: $store->fruit_aisle( [$grape, $tomato] ); Our C C is parameterized, meaning, that the C C can contain nothing but C objects as array values. If you try to pass in a reference to a array using C objects as array values for example, Moose will complain: Attribute (fruit_aisle) does not pass the type constraint (ArrayRef[Str]) =head2 Dumping the contents of an ArrayRef In order to dump the contents of a C object attribute, you must first de-reference the C, and then enumerate over it's keys. You can add this method for showing the store's inventory to the C object shown in the SYNOPSIS: sub show_inventory { my $self = shift; foreach my $item ( @{$self->fruit_aisle} ) { # ... access each Fruit object } } =head2 Assigning arrays to an ArrayRef will overwrite existing arrays Once you create an object containing a C attribute, if you assign a new array reference to that attribute, it will replace any existing array reference: # replace existing inventory my $grape = Fruit->new(name => 'grape', species => 'V. vinifera'); my $tomato = Fruit->new(name => 'tomato', species => 'S. lycopersicum'); $store->fruit_aisle( [$grape, $tomato] ); =head2 Appending/Deleting values to/from an ArrayRef In order to append new elements to an array referred to by the C attribute, you will need to make a copy of the array first, add your new array elements, then assign your modified copy back to the C attribute: my @fruit_aisle_copy = @{$store->fruit_aisle}; my $avocado = Fruit->new(name => 'avocado', species => 'P. americana'); push(@fruit_aisle_copy, $avocado); $store->fruit_aisle( \@fruit_aisle_copy ); And here's an example of deleting an object stored in an ArrayRef: my @fruit_aisle_copy = @{$store->fruit_aisle}; # new array to hold the fruit objects that won't be deleted my @reworked_fruit_aisle; for my $fruit_obj ( @fruit_aisle_copy ) { if ( $fruit_obj->name ne 'tomato' ) { push(@reworked_fruit_aisle, $fruit_obj); } } $store->fruit_aisle( \@reworked_fruit_aisle ); Putting the above code into their own object methods would make appending to or deleting from an C a trivial operation. =head2 Clearing an ArrayRef Assigning C to clear an C will not work because the attribute was originally defined with a type constraint, meaning that attribute must have 0 or more of that type of value to be valid. C in Perl is not a value, so it won't work for clearing the C. If you assign an empty anonymous hash to a C attribute, this will clear out that attribute yet still satisfy the type constraint. # this clears the ArrayRef $store->fruit_aisle( [ ] ); =head1 SEE ALSO =over 4 =item L - Subtypes, and modeling a simple Company class hierarchy =item L - Snippets of code for using Types and Type Constraints =item L - Type constraints that Moose can use and the tools to extend them or create your own. =item L - Autoboxed wrappers for Native Perl datatypes =item L - Extends attribute interfaces =back =head1 AUTHOR Brian Manning =head1 COPYRIGHT AND LICENSE Copyright 2006-2008 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