bah
[gitmo/Moose.git] / lib / Moose / Cookbook / Snack / ArrayRef.pod
1
2 =pod
3
4 =head1 NAME
5
6 Moose::Cookbook::Snack::ArrayRef - Using the ArrayRef type constraint
7
8 =head1 SYNOPSIS
9
10     package Fruit;
11     use Moose;
12
13     has 'name' => (is => 'rw', required => 1);
14     has 'species' => (is => 'rw', required => 1);
15
16     package ProduceStore;
17     use Moose;
18     use Moose::Util::TypeConstraints;
19
20     has 'fruit_aisle' => (isa => 'ArrayRef[Fruit]', is => 'rw');
21
22     package main;
23
24     # we need something to put in the fruit aisle
25     my $orange = Fruit->new(name => 'orange', species => 'C. sinensis');
26     my $apple = Fruit->new(name => 'apple', species => 'M. domestica');
27     my @fruit = ($apple, $orange);
28     my $store = ProduceStore->new(fruit_aisle => \@fruit);
29     
30 =head1 DESCRIPTION
31
32 The ArrayRef type constraint is used to store a reference to a Perl list or
33 array variable as an attribute of a Moose object.
34
35 =head2 Disclaimer
36
37 The code in this document will work on Moose as advertised, but the developers
38 strongly recommend using something like L<Moose::Autobox> or
39 L<MooseX::AttributeHelpers> when working with array references in order to
40 help keep your Moose objects nice and encapsulated.
41
42 =head2 Assigning arrays to an ArrayRef attribute
43
44 Once a Moose-based object with an C<ArrayRef> attribute has been created, you
45 can pass an array (by reference) to that object attribute using that
46 attribute's accessor.  This is how we assign the apple and orange to the
47 store's C<fruit_aisle> C<ArrayRef> attribute, we pass an array containing both
48 objects by reference to the C<fruit_aisle> attribute:
49
50     my @fruit = ($apple, $orange);
51     my $store = ProduceStore->new(fruit_aisle => \@fruit);
52
53 Or you can pass an anonymous array to the C<ArrayRef> attribute as well.  If
54 you created two new objects, C<$grape> and C<$tomato>, and assigned them to
55 the C<ArrayRef>, they would replace the apple and the orange in the store's
56 fruit aisle:
57
58     $store->fruit_aisle( [$grape, $tomato] );
59
60 Our C<fruit_aisle> C<ArrayRef> is parameterized, meaning, that the
61 C<fruit_aisle> C<ArrayRef> can contain nothing but C<Fruit> objects as array
62 values.  If you try to pass in a reference to a array using C<Str> objects as
63 array values for example, Moose will complain: 
64
65     Attribute (fruit_aisle) does not pass the type constraint (ArrayRef[Str])
66
67 =head2 Dumping the contents of an ArrayRef
68
69 In order to dump the contents of a C<ArrayRef> object attribute, you must first
70 de-reference the C<ArrayRef>, and then enumerate over it's keys.  You can add
71 this method for showing the store's inventory to the C<ProduceStore>
72 object shown in the SYNOPSIS:
73
74     sub show_inventory {
75         my $self = shift;
76         foreach my $item ( @{$self->fruit_aisle} ) {
77             # ... access each Fruit object
78         }
79     }
80
81 =head2 Assigning arrays to an ArrayRef will overwrite existing arrays
82
83 Once you create an object containing a C<ArrayRef> attribute, if you assign a
84 new array reference to that attribute, it will replace any existing array
85 reference:
86
87     # replace existing inventory
88     my $grape = Fruit->new(name => 'grape', species => 'V. vinifera');
89     my $tomato = Fruit->new(name => 'tomato', species => 'S. lycopersicum');
90     $store->fruit_aisle( [$grape, $tomato] ); 
91
92 =head2 Appending/Deleting values to/from an ArrayRef
93
94 In order to append new elements to an array referred to by the C<ArrayRef>
95 attribute, you will need to make a copy of the array first, add your new array
96 elements, then assign your modified copy back to the C<ArrayRef> attribute:
97
98     my @fruit_aisle_copy = @{$store->fruit_aisle};
99     my $avocado = Fruit->new(name => 'avocado', species => 'P. americana');
100     push(@fruit_aisle_copy, $avocado);
101     $store->fruit_aisle( \@fruit_aisle_copy );
102
103 And here's an example of deleting an object stored in an ArrayRef:
104
105     my @fruit_aisle_copy = @{$store->fruit_aisle};
106     # new array to hold the fruit objects that won't be deleted
107     my @reworked_fruit_aisle;
108     for my $fruit_obj ( @fruit_aisle_copy ) {
109         if ( $fruit_obj->name ne 'tomato' ) {
110             push(@reworked_fruit_aisle, $fruit_obj);
111         }
112     }
113     $store->fruit_aisle( \@reworked_fruit_aisle );
114
115 Putting the above code into their own object methods would make appending to or deleting from an C<ArrayRef> a trivial operation.
116
117 =head2 Clearing an ArrayRef
118
119 Assigning C<undef> to clear an C<ArrayRef> will not work because the attribute
120 was originally defined with a type constraint, meaning that attribute must have
121 0 or more of that type of value to be valid.  C<undef> in Perl is not a value,
122 so it won't work for clearing the C<ArrayRef>.
123
124 If you assign an empty anonymous hash to a C<ArrayRef> attribute, this will
125 clear out that attribute yet still satisfy the type constraint.
126
127     # this clears the ArrayRef 
128     $store->fruit_aisle( [ ] );
129
130 =head1 SEE ALSO
131
132 =over 4
133
134 =item L<Moose::Cookbook::Recipe4> - Subtypes, and modeling a simple Company
135 class hierarchy
136
137 =item L<Moose::Cookbook::Snack::Types> - Snippets of code for using Types and
138 Type Constraints
139
140 =item L<Moose::Util::TypeConstraints> - Type constraints that Moose can use
141 and the tools to extend them or create your own.
142
143 =item L<Moose::Autobox> - Autoboxed wrappers for Native Perl datatypes
144
145 =item L<MooseX::AttributeHelpers> - Extends attribute interfaces
146
147 =back
148
149 =head1 AUTHOR
150
151 Brian Manning <elspicyjack at gmail dot com>
152
153 =head1 COPYRIGHT AND LICENSE
154
155 Copyright 2006-2008 by Infinity Interactive, Inc.
156
157 L<http://www.iinteractive.com>
158
159 This library is free software; you can redistribute it and/or modify
160 it under the same terms as Perl itself.
161
162 =cut