A few tweaks.
[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
6bf6edf6 15 has 'name' => (is => 'rw', required => 1);
16 has 'species' => (is => 'rw', required => 1);
686a7f09 17
18 package ProduceStoreArray;
19 use Moose;
20 use Moose::Util::TypeConstraints;
21
6bf6edf6 22 has 'fruit_aisle' => (isa => 'ArrayRef[Fruit]', is => 'rw');
686a7f09 23
24 package main;
25
26 # we need something to put in the fruit aisle
6bf6edf6 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);
fbde43ee 30 my $store = ProduceStoreArray->new(fruit_aisle => \@fruit);
686a7f09 31
32=head1 DESCRIPTION
33
34The ArrayRef type constraint is used to store a reference to a Perl list or
35array variable as an attribute of a Moose object.
36
6bf6edf6 37=head2 Disclaimer
38
39The code in this document will work on Moose as advertised, but the developers
40strongly recommend using something like L<Moose::Autobox> or
41L<MooseX::AttributeHelpers> when working with array references in order to
42help keep your Moose objects nice and encapsulated.
43
686a7f09 44=head2 Assigning arrays to an ArrayRef attribute
45
46Once a Moose-based object with an C<ArrayRef> attribute has been created, you
47can pass an array (by reference) to that object attribute using that
48attribute's accessor. This is how we assign the apple and orange to the
49store's C<fruit_aisle> C<ArrayRef> attribute, we pass an array containing both
50objects by reference to the C<fruit_aisle> attribute:
51
6bf6edf6 52 my @fruit = ($apple, $orange);
fbde43ee 53 my $store = ProduceStoreArray->new(fruit_aisle => \@fruit);
686a7f09 54
6bf6edf6 55Or you can pass an anonymous array to the C<ArrayRef> attribute as well. If
56you created two new objects, C<$grape> and C<$tomato>, and assigned them to
57the C<ArrayRef>, they would replace the apple and the orange in the store's
58fruit aisle:
686a7f09 59
6bf6edf6 60 $store->fruit_aisle( [$grape, $tomato] );
686a7f09 61
62Our C<fruit_aisle> C<ArrayRef> is parameterized, meaning, that the
63C<fruit_aisle> C<ArrayRef> can contain nothing but C<Fruit> objects as array
64values. If you try to pass in a reference to a array using C<Str> objects as
65array 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
71In order to dump the contents of a C<ArrayRef> object attribute, you must first
72de-reference the C<ArrayRef>, and then enumerate over it's keys. You can add
73this method for showing the store's inventory to the C<ProduceStoreArray>
74object 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
85Once you create an object containing a C<ArrayRef> attribute, if you assign a
86new array reference to that attribute, it will replace any existing array
87reference:
88
89 # replace existing inventory
6bf6edf6 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] );
686a7f09 93
94=head2 Appending/Deleting values to/from an ArrayRef
95
96In order to append new elements to an array referred to by the C<ArrayRef>
97attribute, you will need to make a copy of the array first, add your new array
98elements, then assign your modified copy back to the C<ArrayRef> attribute:
99
100 my @fruit_aisle_copy = @{$store->fruit_aisle};
6bf6edf6 101 my $avocado = Fruit->new(name => 'avocado', species => 'P. americana');
686a7f09 102 push(@fruit_aisle_copy, $avocado);
103 $store->fruit_aisle( \@fruit_aisle_copy );
104
105And 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 ) {
6bf6edf6 111 if ( $fruit_obj->name ne 'tomato' ) {
686a7f09 112 push(@reworked_fruit_aisle, $fruit_obj);
6bf6edf6 113 } # if ( $fruit_obj->name ne 'tomato' )
686a7f09 114 } # for my $fruit_obj ( @fruit_aisle_copy )
115 $store->fruit_aisle( \@reworked_fruit_aisle );
116
117Putting 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
121Assigning C<undef> to clear an C<ArrayRef> will not work because the attribute
122was originally defined with a type constraint, meaning that attribute must have
1230 or more of that type of value to be valid. C<undef> in Perl is not a value,
124so it won't work for clearing the C<ArrayRef>.
125
126If you assign an empty anonymous hash to a C<ArrayRef> attribute, this will
127clear 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
137class hierarchy
138
139=item L<Moose::Cookbook::Snack::Types> - Snippets of code for using Types and
140Type Constraints
141
142=item L<Moose::Util::TypeConstraints> - Type constraints that Moose can use
143
6bf6edf6 144=item L<Moose::Autobox> - Autoboxed wrappers for Native Perl datatypes
145
146=item L<MooseX::AttributeHelpers> - Extends attribute interfaces
147
686a7f09 148=back
149
150=head1 AUTHOR
151
152Brian Manning <elspicyjack at gmail dot com>
153
154=head1 COPYRIGHT AND LICENSE
155
6bf6edf6 156Copyright (c)2008 by Infinity Interactive, Inc., Brian Manning
686a7f09 157
158This documentation is free software; you can redistribute it and/or modify
159it under the same terms as Perl itself.
160
161=cut