1Sub::HandlesVia::ManualU:s:eArdvCaonncterdi(b3u)ted PerlSuDbo:c:uHmaenndtlaetsiVoina::Manual::Advanced(3)
2
3
4

NAME

6       Sub::HandlesVia::Manual::Advanced - misc advanced documentation
7

MANUAL

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

BUGS

187       Please report any bugs to
188       <https://github.com/tobyink/p5-sub-handlesvia/issues>.
189

SEE ALSO

191       Sub::HandlesVia.
192

AUTHOR

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

DISCLAIMER OF WARRANTIES

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.38.0                      2023-07-2S1ub::HandlesVia::Manual::Advanced(3)
Impressum