1Moose::Manual::DelegatiUosne(r3)Contributed Perl DocumenMtoaotsieo:n:Manual::Delegation(3)
2
3
4
6 Moose::Manual::Delegation - Attribute delegation
7
9 Delegation is a feature that lets you create "proxy" methods that do
10 nothing more than call some other method on an attribute. This is quite
11 handy since it lets you simplify a complex set of "has-a" relationships
12 and present a single unified API from one class.
13
14 With delegation, consumers of a class don't need to know about all the
15 objects it contains, reducing the amount of API they need to learn.
16
17 Delegations are defined as a mapping between one or more methods
18 provided by the "real" class (the delegatee), and a set of
19 corresponding methods in the delegating class. The delegating class can
20 re-use the method names provided by the delegatee or provide its own
21 names.
22
23 Delegation is also a great way to wrap an existing class, especially a
24 non-Moose class or one that is somehow hard (or impossible) to
25 subclass.
26
28 Moose offers a number of options for defining a delegation's mapping,
29 ranging from simple to complex.
30
31 The simplest form is to simply specify a list of methods:
32
33 package Website;
34
35 use Moose;
36
37 has 'uri' => (
38 is => 'ro',
39 isa => 'URI',
40 handles => [qw( host path )],
41 );
42
43 With this definition, we can call "$website->host" and it "just works".
44 Under the hood, Moose will call "$website->uri->host" for you. Note
45 that $website is not automatically passed to the "host" method; the
46 invocant is "$website->uri".
47
48 We can also define a mapping as a hash reference. This allows you to
49 rename methods as part of the mapping:
50
51 package Website;
52
53 use Moose;
54
55 has 'uri' => (
56 is => 'ro',
57 isa => 'URI',
58 handles => {
59 hostname => 'host',
60 path => 'path',
61 },
62 );
63
64 In this example, we've created a "$website->hostname" method, rather
65 than using "URI.pm"'s name, "host".
66
67 These two mapping forms are the ones you will use most often. The
68 remainder are a bit more complex, and less common.
69
70 has 'uri' => (
71 is => 'ro',
72 isa => 'URI',
73 handles => qr/^(?:host|path|query.*)/,
74 );
75
76 This is similar to the array version, except it uses the regex to match
77 against all the methods provided by the delegatee. In order for this to
78 work, you must provide an "isa" parameter for the attribute, and it
79 must be a class. Moose uses this to introspect the delegatee class and
80 determine what methods it provides.
81
82 You can use a role name as the value of "handles":
83
84 has 'uri' => (
85 is => 'ro',
86 isa => 'URI',
87 handles => 'HasURI',
88 );
89
90 Moose will introspect the role to determine what methods it provides
91 and create a mapping for each of those methods.
92
93 Finally, you can also provide a sub reference to generate a mapping.
94 You probably won't need this version often (if ever). See the Moose
95 docs for more details on exactly how this works.
96
98 Handles also will allow you to delegate to "helper" methods that work
99 on common Perl data structures. If you remember or have ever used
100 MooseX::AttributeHelpers the mechanism is very similar.
101
102 has 'queue' => (
103 isa => 'ArrayRef[Item]',
104 traits => ['Array'],
105 default => sub { [ ] },
106 handles => {
107 add_item => 'push',
108 next_item => 'shift',
109 },
110 )
111
112 By providing the "Array" trait to the "traits" parameter you signal to
113 Moose that you would like to use the set of Array helpers. Moose will
114 then create "add_item" and "next_item" method that "just works". Behind
115 the scenes "add_item" is something like
116
117 sub add_item {
118 my ($self, @items) = @_;
119
120 for my $item (@items) {
121 $Item_TC->validate($item);
122 }
123
124 push @{ $self->queue }, @items;
125 }
126
127 There are traits for not only "Array" but also "Hash", "Bool",
128 "String", "Number", and "Counter". For more information see the
129 documentation in Moose::Meta::Attribute::Native.
130
132 Currying is a way of creating a method or function from another method
133 or function with some of the parameters pre-defined. Moose provides the
134 ability to curry methods when creating delegates.
135
136 package Spider;
137 use Moose;
138
139 has request => (
140 is => 'ro'
141 isa => 'HTTP::Request',
142 handles => {
143 set_user_agent => [ header => 'UserAgent' ],
144 },
145 )
146
147 With this definition, calling "$spider->set_user_agent('MyClient')"
148 will behind the scenes call "$spider->request->header('UserAgent',
149 'MyClient')".
150
152 It is perfectly valid to delegate methods to an attribute which is not
153 required or can be undefined. When a delegated method is called, Moose
154 will throw a runtime error if the attribute does not contain an object.
155
157 Dave Rolsky <autarch@urth.org>
158
160 Copyright 2009 by Infinity Interactive, Inc.
161
162 <http://www.iinteractive.com>
163
164 This library is free software; you can redistribute it and/or modify it
165 under the same terms as Perl itself.
166
167
168
169perl v5.12.2 2010-08-20 Moose::Manual::Delegation(3)