Commit | Line | Data |
686a7f09 |
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 |