More manual revision
[gitmo/Moose.git] / lib / Moose / Manual / Delegation.pod
CommitLineData
093a09aa 1=pod
2
3=head1 NAME
4
d67ce58f 5Moose::Manual::Delegation - Attribute delegation
093a09aa 6
7=head1 WHAT IS DELEGATION?
8
54c97a15 9Delegation is a feature that lets you create "proxy" methods that do nothing
10more than call some other method on an attribute. This lets you simplify a
11complex set of "has-a" relationships and present a single unified API from one
12class.
093a09aa 13
d3e02c74 14With delegation, consumers of a class don't need to know about all the
15objects it contains, reducing the amount of API they need to learn.
093a09aa 16
17Delegations are defined as a mapping between one or more methods
18provided by the "real" class (the delegatee), and a set of
19corresponding methods in the delegating class. The delegating class
d3e02c74 20can re-use the method names provided by the delegatee or provide its
093a09aa 21own names.
22
23Delegation is also a great way to wrap an existing class, especially a
24non-Moose class or one that is somehow hard (or impossible) to
25subclass.
26
27=head1 DEFINING A MAPPING
28
29Moose offers a number of options for defining a delegation's mapping,
30ranging from simple to complex.
31
32The simplest form is to simply specify a list of methods:
33
34 package Website;
35
36 use Moose;
37
38 has 'uri' => (
39 is => 'ro',
40 isa => 'URI',
41 handles => [qw( host path )],
42 );
43
44With this definition, we can call C<< $website->host >> and it "just
45works". Under the hood, Moose will call C<< $website->uri->host >> for
b3b5ff5a 46you. Note that C<$website> is not automatically passed to the C<host>
47method; the invocant is C<< $website->uri >>.
093a09aa 48
49We can also define a mapping as a hash reference. This allows you to
50rename methods as part of the mapping:
51
52 package Website;
53
54 use Moose;
55
56 has 'uri' => (
57 is => 'ro',
58 isa => 'URI',
59 handles => {
60 hostname => 'host',
61 path => 'path',
62 },
63 );
64
65In this example, we've created a C<< $website->hostname >> method,
66rather than using C<URI.pm>'s name, C<host>.
67
68These two mapping forms are the ones you will use most often. The
54c97a15 69remaining methods are a bit more complex.
093a09aa 70
71 has 'uri' => (
72 is => 'ro',
73 isa => 'URI',
74 handles => qr/^(?:host|path|query.*)/,
75 );
76
77This is similar to the array version, except it uses the regex to
78match against all the methods provided by the delegatee. In order for
79this to work, you must provide an C<isa> parameter for the attribute,
80and it must be a class. Moose uses this to introspect the delegatee
81class and determine what methods it provides.
82
83You can use a role name as the value of C<handles>:
84
85 has 'uri' => (
86 is => 'ro',
87 isa => 'URI',
88 handles => 'HasURI',
89 );
90
91Moose will introspect the role to determine what methods it provides
92and create a mapping for each of those methods.
93
94Finally, you can also provide a sub reference to I<generate> a
95mapping. You probably won't need this version often (if ever). See the
96L<Moose> docs for more details on exactly how this works.
97
54c97a15 98=head1 NATIVE TRAIT DELEGATION
50f346d7 99
54c97a15 100The Native Traits feature allows standard Perl data structures to be treated
101as if they were objects for the purposes of delegation.
f4c5daeb 102
50f346d7 103 has 'queue' => (
f4c5daeb 104 traits => ['Array'],
54c97a15 105 isa => 'ArrayRef[Item]',
50f346d7 106 default => sub { [ ] },
107 handles => {
f4c5daeb 108 add_item => 'push',
50f346d7 109 next_item => 'shift',
9610c1d2 110 },
50f346d7 111 )
112
54c97a15 113By providing the C<Array> trait to the C<traits> parameter you tell Moose that
114you would like to use the set of Array helpers. Moose will then create
115C<add_item> and C<next_item> methods that "just works". Behind the scenes
116C<add_item> is something like
50f346d7 117
f4c5daeb 118 sub add_item {
50f346d7 119 my ($self, @items) = @_;
26366034 120
f4c5daeb 121 for my $item (@items) {
122 $Item_TC->validate($item);
123 }
26366034 124
50f346d7 125 push @{ $self->queue }, @items;
126 }
127
54c97a15 128Moose includes the following native traits:
129
130=over 4
131
132=item * L<Array|Moose::Meta::Attribute::Native::Trait::Array>
133
134=item * L<Bool|Moose::Meta::Attribute::Native::Trait::Bool>
135
136=item * L<Code|Moose::Meta::Attribute::Native::Trait::Code>
137
138=item * L<Counter|Moose::Meta::Attribute::Native::Trait::Counter>
139
140=item * L<Hash|Moose::Meta::Attribute::Native::Trait::Hash>
141
142=item * L<Number|Moose::Meta::Attribute::Native::Trait::Number>
143
144=item * L<String|Moose::Meta::Attribute::Native::Trait::String>
145
146=back
50f346d7 147
148=head1 CURRYING
149
54c97a15 150Currying allows you to create a method with some pre-set parameters. You can
151create a curried delegation method:
50f346d7 152
153 package Spider;
154 use Moose;
155
156 has request => (
26366034 157 is => 'ro'
158 isa => 'HTTP::Request',
50f346d7 159 handles => {
26366034 160 set_user_agent => [ header => 'UserAgent' ],
9610c1d2 161 },
50f346d7 162 )
163
8580644d 164With this definition, calling C<< $spider->set_user_agent('MyClient') >> will
54c97a15 165call C<< $spider->request->header('UserAgent', 'MyClient') >> behind the
166scenes.
167
168Note that with currying, the currying always start with the first parameter to
169a method (C<$_[0]). Any arguments you pass to the delegation come after the
170curried arguments.
50f346d7 171
093a09aa 172=head1 MISSING ATTRIBUTES
173
174It is perfectly valid to delegate methods to an attribute which is not
d3e02c74 175required or can be undefined. When a delegated method is called, Moose
176will throw a runtime error if the attribute does not contain an
177object.
093a09aa 178
179=head1 AUTHOR
180
181Dave Rolsky E<lt>autarch@urth.orgE<gt>
182
183=head1 COPYRIGHT AND LICENSE
184
2840a3b2 185Copyright 2009 by Infinity Interactive, Inc.
093a09aa 186
187L<http://www.iinteractive.com>
188
189This library is free software; you can redistribute it and/or modify
190it under the same terms as Perl itself.
191
192=cut