- initial commit of new snacks (short documents) for ArrayRef's, HashRef's and
[gitmo/Moose.git] / lib / Moose / Cookbook / Snack / ArrayRef.pod
1 #!/usr/bin/env perl
2 =pod
3
4 =head1 NAME
5
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.
9
10 =head1 SYNOPSIS
11
12     package Fruit;
13     use Moose;
14
15     has q(name) => ( is => q(rw), required => 1 );
16     has q(species) => ( is => q(rw), required => 1 );
17
18     package ProduceStoreArray;
19     use Moose;
20     use Moose::Util::TypeConstraints;
21
22     has q(fruit_aisle) => ( is => q(rw), isa => q(ArrayRef[Fruit]) );
23
24     package main;
25
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 );
33     
34 =head1 DESCRIPTION
35
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.
38
39 =head2 Assigning arrays to an ArrayRef attribute
40
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:
46
47     my @fruit = ( $apple, $orange );
48     my $store = ProduceStore->new( fruit_aisle => \@fruit );
49
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.
53
54     $store->fruit_aisle( [ $grape, $tomato ] );
55
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: 
60
61     Attribute (fruit_aisle) does not pass the type constraint (ArrayRef[Str])
62
63 =head2 Dumping the contents of an ArrayRef
64
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:
69
70     sub show_inventory {
71         my $self = shift;
72         foreach my $item ( @{$self->fruit_aisle} ) {
73             # access each Fruit object
74         } # foreach my $item ( @{$self->fruit_aisle} ) 
75     }
76
77 =head2 Assigning arrays to an ArrayRef will overwrite existing arrays
78
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
81 reference:
82
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 ] ); 
89
90 =head2 Appending/Deleting values to/from an ArrayRef
91
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:
95
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 );
101
102 And here's an example of deleting an object stored in an ArrayRef:
103
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 );
113
114 Putting the above code into their own object methods would make appending to or deleting from an C<ArrayRef> a trivial operation.
115
116 =head2 Clearing an ArrayRef
117
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>.
122
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.
125
126     # this clears the ArrayRef 
127     $store->fruit_aisle( [ ] );
128
129 =head1 SEE ALSO
130
131 =over 4
132
133 =item L<Moose::Cookbook::Recipe4> - Subtypes, and modeling a simple Company
134 class hierarchy
135
136 =item L<Moose::Cookbook::Snack::Types> - Snippets of code for using Types and
137 Type Constraints
138
139 =item L<Moose::Util::TypeConstraints> - Type constraints that Moose can use
140
141 =back
142
143 =head1 AUTHOR
144
145 Brian Manning <elspicyjack at gmail dot com>
146
147 =head1 COPYRIGHT AND LICENSE
148
149 Copyright (c)2008 by Brian Manning
150
151 This documentation is free software; you can redistribute it and/or modify
152 it under the same terms as Perl itself.
153
154 =cut