1Sub::HandlesVia::ManualU:s:eArdvCaonncterdi(b3u)ted PerlSuDbo:c:uHmaenndtlaetsiVoina::Manual::Advanced(3)
2
3
4
6 Sub::HandlesVia::Manual::Advanced - misc advanced documentation
7
9 The following information applies no matter which OO toolkit you are
10 using.
11
12 Method Chaining
13 Say you have the following
14
15 handles_via => 'Array',
16 handles => {
17 'add_food' => 'push',
18 'find_food' => 'grep',
19 'remove_food' => 'pop',
20 },
21
22 Now "$kitchen->remove_food" will remove the last food on the list and
23 return it. But what if we don't care about what food was removed? We
24 just want to remove the food and discard it. You can do this:
25
26 handles_via => 'Array',
27 handles => {
28 'add_food' => 'push',
29 'find_food' => 'grep',
30 'remove_food' => 'pop...',
31 },
32
33 Now the "remove_food" method will return the kitchen object instead of
34 returning the food. This makes it suitable for chaining method calls:
35
36 # remove the three most recent foods
37 $kitchen->remove_food->remove_food->remove_food;
38
39 Delegating to CodeRefs
40 You can delegate to coderefs:
41
42 handles_via => 'Array',
43 handles => {
44 'find_healthiest' => sub { my $foods = shift; ... },
45 }
46
47 Delegating to Named Methods
48 The Sub::HandlesVia::HandlerLibrary::Blessed handler library allows you
49 to delegate to named methods of a blessed object.
50
51 isa => InstanceOf['HTTP::Tiny'],
52 handles_via => 'Blessed',
53 handles => {
54 'http_get' => 'get',
55 'http_post' => 'post',
56 },
57
58 However, in Moo, Moose, Mouse, and Mite, this kind of delegation is
59 baked in, so you don't even need Sub::HandlesVia!
60
61 isa => InstanceOf['HTTP::Tiny'],
62 handles => {
63 'http_get' => 'get',
64 'http_post' => 'post',
65 },
66
67 Still, the Sub::HandlesVia::HandlerLibrary::Blessed handler library may
68 still be useful if you wish to use other Sub::HandlesVia features like
69 chaining, or if you're using a different OO toolkit.
70
71 An example of combining delegation to named methods with "native trait"
72 style delegation... let's say "FoodList" is a class where instances are
73 blessed arrayrefs of strings.
74
75 isa => InstanceOf['FoodList'],
76 handles_via => 'Array', 'Blessed',
77 handles => {
78 'find_food' => 'grep',
79 'find_healthiest_food' => 'find_healthiest',
80 },
81
82 Now "$kitchen->find_food($coderef)" does this (which breaks
83 encapsulation ):
84
85 my @result = grep $coderef->(), @{ $kitchen->food };
86
87 But because "find_healthiest" isn't one of the methods offered by
88 Sub::HandlesVia::HandlerList::Array, Sub::HandlesVia assumes you want
89 to call it on the arrayref like a proper method, so
90 "$kitchen->find_healthiest_food" does this:
91
92 $kitchen->food->find_healthiest
93
94 It can be useful to be explicit about which methods you wish to
95 delegate to a "native trait" style array and which are named methods to
96 be called on a blessed object:
97
98 isa => InstanceOf['FoodList'],
99 handles_via => [ 'Array', 'Blessed' ],
100 handles => {
101 'find_food' => 'Array->grep',
102 'find_healthiest_food' => 'Blessed->find_healthiest',
103 },
104
105 See "Delegating to Multiple Handler Libraries".
106
107 Curried Arguments
108 All this talk of food is making me hungry, but as much as I'd like to
109 eat a curry right now, that's not the kind of currying we're talking
110 about.
111
112 handles_via => 'Array',
113 handles => {
114 'get_food' => 'get',
115 },
116
117 "$kitchen->get_food(0)" will return the first item on the list.
118 "$kitchen->get_food(1)" will return the second item on the list. And
119 so on.
120
121 handles_via => 'Array',
122 handles => {
123 'first_food' => [ 'get' => 0 ],
124 'second_food' => [ 'get' => 1 ],
125 },
126
127 I think you already know what this does. Right?
128
129 And yes, currying works with coderefs.
130
131 handles_via => 'Array',
132 handles => {
133 'blargy' => [ sub { ... }, @curried ],
134 },
135
136 Looser Argument Checking
137 Sub::HandlesVia tries to be strict by default. For example, if your
138 attribute specifies "isa => ArrayRef[Int]" then your method which
139 delegates to "push" will check that its arguments are integers.
140
141 You can tell it to be less rigourous checking method arguments using
142 the "~" prefix:
143
144 handles_via => 'Array',
145 handles => {
146 'find_food' => '~grep',
147 },
148
149 Delegating to Multiple Handler Libraries
150 Sometimes you may wish to pick methods to delegate to from multiple
151 handler libraries. This is possible by setting "handles_via" to an
152 arrayref.
153
154 isa => ArrayRef|HashRef,
155 handles_via => [ 'Array', 'Hash' ],
156 handles => {
157 the_keys => 'keys',
158 ship_shape => 'sort_in_place',
159 }
160
161 Here you have an attribute which might be an arrayref or a hashref.
162 When it's an arrayref, "$object->ship_shape" will work nicely, but
163 "$object->the_keys" will fail badly.
164
165 Still, this sort of thing can kind of make sense if you have an object
166 that overloads both "@{}" and "%{}".
167
168 In particular, the Sub::HandlesVia::HandlerLibrary::Scalar library
169 often makes sense to combine with the other libraries because strings,
170 integers, numbers, booleans, and even arrayrefs, hashrefs, and
171 coderefs, are all scalars.
172
173 Sometimes a method name will be ambiguous. For example, there's a "get"
174 method for both hashes and arrays. In this case, the array one will win
175 because you listed it first in "handles_via".
176
177 But you can be specific:
178
179 isa => ArrayRef|HashRef,
180 handles_via => [ 'Array', 'Hash' ],
181 handles => {
182 get_by_index => 'Array->get',
183 get_by_key => 'Hash->get',
184 }
185
187 Please report any bugs to
188 <https://github.com/tobyink/p5-sub-handlesvia/issues>.
189
191 Sub::HandlesVia.
192
194 Toby Inkster <tobyink@cpan.org>.
195
197 This software is copyright (c) 2022 by Toby Inkster.
198
199 This is free software; you can redistribute it and/or modify it under
200 the same terms as the Perl 5 programming language system itself.
201
203 THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
204 WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
205 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
206
207
208
209perl v5.36.0 2023-04-0S6ub::HandlesVia::Manual::Advanced(3)