- initial commit of new snacks (short documents) for ArrayRef's, HashRef's and
[gitmo/Moose.git] / lib / Moose / Cookbook / Snack / ArrayRef.pod
CommitLineData
686a7f09 1#!/usr/bin/env perl
2=pod
3
4=head1 NAME
5
6Moose::Cookbook::Snack::ArrayRef - (Ab)using the ArrayRef type constraint
7provided by the L<Moose::Util::TypeConstraint> and/or
8L<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
36The ArrayRef type constraint is used to store a reference to a Perl list or
37array variable as an attribute of a Moose object.
38
39=head2 Assigning arrays to an ArrayRef attribute
40
41Once a Moose-based object with an C<ArrayRef> attribute has been created, you
42can pass an array (by reference) to that object attribute using that
43attribute's accessor. This is how we assign the apple and orange to the
44store's C<fruit_aisle> C<ArrayRef> attribute, we pass an array containing both
45objects by reference to the C<fruit_aisle> attribute:
46
47 my @fruit = ( $apple, $orange );
48 my $store = ProduceStore->new( fruit_aisle => \@fruit );
49
50Or you can pass an anonymous array to the C<ArrayRef> attribute as well.
51This is shown in the example when the grape and tomato replace the apple
52and the orange in the store's fruit aisle.
53
54 $store->fruit_aisle( [ $grape, $tomato ] );
55
56Our C<fruit_aisle> C<ArrayRef> is parameterized, meaning, that the
57C<fruit_aisle> C<ArrayRef> can contain nothing but C<Fruit> objects as array
58values. If you try to pass in a reference to a array using C<Str> objects as
59array 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
65In order to dump the contents of a C<ArrayRef> object attribute, you must first
66de-reference the C<ArrayRef>, and then enumerate over it's keys. You can add
67this method for showing the store's inventory to the C<ProduceStoreArray>
68object 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
79Once you create an object containing a C<ArrayRef> attribute, if you assign a
80new array reference to that attribute, it will replace any existing array
81reference:
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
92In order to append new elements to an array referred to by the C<ArrayRef>
93attribute, you will need to make a copy of the array first, add your new array
94elements, 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
102And 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
114Putting 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
118Assigning C<undef> to clear an C<ArrayRef> will not work because the attribute
119was originally defined with a type constraint, meaning that attribute must have
1200 or more of that type of value to be valid. C<undef> in Perl is not a value,
121so it won't work for clearing the C<ArrayRef>.
122
123If you assign an empty anonymous hash to a C<ArrayRef> attribute, this will
124clear 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
134class hierarchy
135
136=item L<Moose::Cookbook::Snack::Types> - Snippets of code for using Types and
137Type Constraints
138
139=item L<Moose::Util::TypeConstraints> - Type constraints that Moose can use
140
141=back
142
143=head1 AUTHOR
144
145Brian Manning <elspicyjack at gmail dot com>
146
147=head1 COPYRIGHT AND LICENSE
148
149Copyright (c)2008 by Brian Manning
150
151This documentation is free software; you can redistribute it and/or modify
152it under the same terms as Perl itself.
153
154=cut