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