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