6 Moose::Cookbook::Snack::ArrayRef - (Ab)using the ArrayRef type constraint
7 provided by the L<Moose::Util::TypeConstraint> and/or
8 L<Moose::Util::TypeConstraints::OptimizedConstraints> classes.
15 has q(name) => ( is => q(rw), required => 1 );
16 has q(species) => ( is => q(rw), required => 1 );
18 package ProduceStoreArray;
20 use Moose::Util::TypeConstraints;
22 has q(fruit_aisle) => ( is => q(rw), isa => q(ArrayRef[Fruit]) );
26 # we need something to put in the fruit aisle
27 my $orange = Fruit->new(
28 name => q(orange), species => q(C. sinensis) );
29 my $apple = Fruit->new(
30 name => q(apple), species => q(M. domestica) );
31 my @fruit = ( $apple, $orange );
32 my $store = ProduceStore->new( fruit_aisle => \@fruit );
36 The ArrayRef type constraint is used to store a reference to a Perl list or
37 array variable as an attribute of a Moose object.
39 =head2 Assigning arrays to an ArrayRef attribute
41 Once a Moose-based object with an C<ArrayRef> attribute has been created, you
42 can pass an array (by reference) to that object attribute using that
43 attribute's accessor. This is how we assign the apple and orange to the
44 store's C<fruit_aisle> C<ArrayRef> attribute, we pass an array containing both
45 objects by reference to the C<fruit_aisle> attribute:
47 my @fruit = ( $apple, $orange );
48 my $store = ProduceStore->new( fruit_aisle => \@fruit );
50 Or you can pass an anonymous array to the C<ArrayRef> attribute as well.
51 This is shown in the example when the grape and tomato replace the apple
52 and the orange in the store's fruit aisle.
54 $store->fruit_aisle( [ $grape, $tomato ] );
56 Our C<fruit_aisle> C<ArrayRef> is parameterized, meaning, that the
57 C<fruit_aisle> C<ArrayRef> can contain nothing but C<Fruit> objects as array
58 values. If you try to pass in a reference to a array using C<Str> objects as
59 array values for example, Moose will complain:
61 Attribute (fruit_aisle) does not pass the type constraint (ArrayRef[Str])
63 =head2 Dumping the contents of an ArrayRef
65 In order to dump the contents of a C<ArrayRef> object attribute, you must first
66 de-reference the C<ArrayRef>, and then enumerate over it's keys. You can add
67 this method for showing the store's inventory to the C<ProduceStoreArray>
68 object shown in the SYNOPSIS:
72 foreach my $item ( @{$self->fruit_aisle} ) {
73 # access each Fruit object
74 } # foreach my $item ( @{$self->fruit_aisle} )
77 =head2 Assigning arrays to an ArrayRef will overwrite existing arrays
79 Once you create an object containing a C<ArrayRef> attribute, if you assign a
80 new array reference to that attribute, it will replace any existing array
83 # replace existing inventory
84 my $grape = Fruit->new(
85 name => q(grape), species => q(V. vinifera) );
86 my $tomato = Fruit->new(
87 name => q(tomato), species => q(S. lycopersicum));
88 $store->fruit_aisle( [ $grape, $tomato ] );
90 =head2 Appending/Deleting values to/from an ArrayRef
92 In order to append new elements to an array referred to by the C<ArrayRef>
93 attribute, you will need to make a copy of the array first, add your new array
94 elements, then assign your modified copy back to the C<ArrayRef> attribute:
96 my @fruit_aisle_copy = @{$store->fruit_aisle};
97 my $avocado = Fruit->new(
98 name => q(avocado), species => q(P. americana) );
99 push(@fruit_aisle_copy, $avocado);
100 $store->fruit_aisle( \@fruit_aisle_copy );
102 And here's an example of deleting an object stored in an ArrayRef:
104 my @fruit_aisle_copy = @{$store->fruit_aisle};
105 # new array to hold the fruit objects that won't be deleted
106 my @reworked_fruit_aisle;
107 for my $fruit_obj ( @fruit_aisle_copy ) {
108 if ( $fruit_obj->name ne q(tomato) ) {
109 push(@reworked_fruit_aisle, $fruit_obj);
110 } # if ( $fruit_obj->name ne q(tomato) )
111 } # for my $fruit_obj ( @fruit_aisle_copy )
112 $store->fruit_aisle( \@reworked_fruit_aisle );
114 Putting the above code into their own object methods would make appending to or deleting from an C<ArrayRef> a trivial operation.
116 =head2 Clearing an ArrayRef
118 Assigning C<undef> to clear an C<ArrayRef> will not work because the attribute
119 was originally defined with a type constraint, meaning that attribute must have
120 0 or more of that type of value to be valid. C<undef> in Perl is not a value,
121 so it won't work for clearing the C<ArrayRef>.
123 If you assign an empty anonymous hash to a C<ArrayRef> attribute, this will
124 clear out that attribute yet still satisfy the type constraint.
126 # this clears the ArrayRef
127 $store->fruit_aisle( [ ] );
133 =item L<Moose::Cookbook::Recipe4> - Subtypes, and modeling a simple Company
136 =item L<Moose::Cookbook::Snack::Types> - Snippets of code for using Types and
139 =item L<Moose::Util::TypeConstraints> - Type constraints that Moose can use
145 Brian Manning <elspicyjack at gmail dot com>
147 =head1 COPYRIGHT AND LICENSE
149 Copyright (c)2008 by Brian Manning
151 This documentation is free software; you can redistribute it and/or modify
152 it under the same terms as Perl itself.