1autodie::hints(3) User Contributed Perl Documentation autodie::hints(3)
2
3
4
6 autodie::hints - Provide hints about user subroutines to autodie
7
9 package Your::Module;
10
11 our %DOES = ( 'autodie::hints::provider' => 1 );
12
13 sub AUTODIE_HINTS {
14 return {
15 foo => { scalar => HINTS, list => SOME_HINTS },
16 bar => { scalar => HINTS, list => MORE_HINTS },
17 }
18 }
19
20 # Later, in your main program...
21
22 use Your::Module qw(foo bar);
23 use autodie qw(:default foo bar);
24
25 foo(); # succeeds or dies based on scalar hints
26
27 # Alternatively, hints can be set on subroutines we've
28 # imported.
29
30 use autodie::hints;
31 use Some::Module qw(think_positive);
32
33 BEGIN {
34 autodie::hints->set_hints_for(
35 \&think_positive,
36 {
37 fail => sub { $_[0] <= 0 }
38 }
39 )
40 }
41 use autodie qw(think_positive);
42
43 think_positive(...); # Returns positive or dies.
44
46 Introduction
47 The autodie pragma is very smart when it comes to working with Perl's
48 built-in functions. The behaviour for these functions are fixed, and
49 "autodie" knows exactly how they try to signal failure.
50
51 But what about user-defined subroutines from modules? If you use
52 "autodie" on a user-defined subroutine then it assumes the following
53 behaviour to demonstrate failure:
54
55 · A false value, in scalar context
56
57 · An empty list, in list context
58
59 · A list containing a single undef, in list context
60
61 All other return values (including the list of the single zero, and the
62 list containing a single empty string) are considered successful.
63 However, real-world code isn't always that easy. Perhaps the code
64 you're working with returns a string containing the word "FAIL" upon
65 failure, or a two element list containing "(undef, "human error
66 message")". To make autodie work with these sorts of subroutines, we
67 have the hinting interface.
68
69 The hinting interface allows hints to be provided to "autodie" on how
70 it should detect failure from user-defined subroutines. While these
71 can be provided by the end-user of "autodie", they are ideally written
72 into the module itself, or into a helper module or sub-class of
73 "autodie" itself.
74
75 What are hints?
76 A hint is a subroutine or value that is checked against the return
77 value of an autodying subroutine. If the match returns true, "autodie"
78 considers the subroutine to have failed.
79
80 If the hint provided is a subroutine, then "autodie" will pass the
81 complete return value to that subroutine. If the hint is any other
82 value, then "autodie" will smart-match against the value provided. In
83 Perl 5.8.x there is no smart-match operator, and as such only
84 subroutine hints are supported in these versions.
85
86 Hints can be provided for both scalar and list contexts. Note that an
87 autodying subroutine will never see a void context, as "autodie" always
88 needs to capture the return value for examination. Autodying
89 subroutines called in void context act as if they're called in a scalar
90 context, but their return value is discarded after it has been checked.
91
92 Example hints
93 Hints may consist of scalars, array references, regular expressions and
94 subroutine references. You can specify different hints for how failure
95 should be identified in scalar and list contexts.
96
97 These examples apply for use in the "AUTODIE_HINTS" subroutine and when
98 calling "autodie::hints-"set_hints_for()>.
99
100 The most common context-specific hints are:
101
102 # Scalar failures always return undef:
103 { scalar => undef }
104
105 # Scalar failures return any false value [default expectation]:
106 { scalar => sub { ! $_[0] } }
107
108 # Scalar failures always return zero explicitly:
109 { scalar => '0' }
110
111 # List failures always return an empty list:
112 { list => [] }
113
114 # List failures return () or (undef) [default expectation]:
115 { list => sub { ! @_ || @_ == 1 && !defined $_[0] } }
116
117 # List failures return () or a single false value:
118 { list => sub { ! @_ || @_ == 1 && !$_[0] } }
119
120 # List failures return (undef, "some string")
121 { list => sub { @_ == 2 && !defined $_[0] } }
122
123 # Unsuccessful foo() returns 'FAIL' or '_FAIL' in scalar context,
124 # returns (-1) in list context...
125 autodie::hints->set_hints_for(
126 \&foo,
127 {
128 scalar => qr/^ _? FAIL $/xms,
129 list => [-1],
130 }
131 );
132
133 # Unsuccessful foo() returns 0 in all contexts...
134 autodie::hints->set_hints_for(
135 \&foo,
136 {
137 scalar => 0,
138 list => [0],
139 }
140 );
141
142 This "in all contexts" construction is very common, and can be
143 abbreviated, using the 'fail' key. This sets both the "scalar" and
144 "list" hints to the same value:
145
146 # Unsuccessful foo() returns 0 in all contexts...
147 autodie::hints->set_hints_for(
148 \&foo,
149 {
150 fail => sub { @_ == 1 and defined $_[0] and $_[0] == 0 }
151 }
152 );
153
154 # Unsuccessful think_positive() returns negative number on failure...
155 autodie::hints->set_hints_for(
156 \&think_positive,
157 {
158 fail => sub { $_[0] < 0 }
159 }
160 );
161
162 # Unsuccessful my_system() returns non-zero on failure...
163 autodie::hints->set_hints_for(
164 \&my_system,
165 {
166 fail => sub { $_[0] != 0 }
167 }
168 );
169
171 If you are using a module which returns something special on failure,
172 then you can manually create hints for each of the desired subroutines.
173 Once the hints are specified, they are available for all files and
174 modules loaded thereafter, thus you can move this work into a module
175 and it will still work.
176
177 use Some::Module qw(foo bar);
178 use autodie::hints;
179
180 autodie::hints->set_hints_for(
181 \&foo,
182 {
183 scalar => SCALAR_HINT,
184 list => LIST_HINT,
185 }
186 );
187 autodie::hints->set_hints_for(
188 \&bar,
189 { fail => SOME_HINT, }
190 );
191
192 It is possible to pass either a subroutine reference (recommended) or a
193 fully qualified subroutine name as the first argument. This means you
194 can set hints on modules that might get loaded:
195
196 use autodie::hints;
197 autodie::hints->set_hints_for(
198 'Some::Module:bar', { fail => SCALAR_HINT, }
199 );
200
201 This technique is most useful when you have a project that uses a lot
202 of third-party modules. You can define all your possible hints in one-
203 place. This can even be in a sub-class of autodie. For example:
204
205 package my::autodie;
206
207 use parent qw(autodie);
208 use autodie::hints;
209
210 autodie::hints->set_hints_for(...);
211
212 1;
213
214 You can now "use my::autodie", which will work just like the standard
215 "autodie", but is now aware of any hints that you've set.
216
218 "autodie" provides a passive interface to allow you to declare hints
219 for your module. These hints will be found and used by "autodie" if it
220 is loaded, but otherwise have no effect (or dependencies) without
221 autodie. To set these, your module needs to declare that it does the
222 "autodie::hints::provider" role. This can be done by writing your own
223 "DOES" method, using a system such as "Class::DOES" to handle the
224 heavy-lifting for you, or declaring a %DOES package variable with a
225 "autodie::hints::provider" key and a corresponding true value.
226
227 Note that checking for a %DOES hash is an "autodie"-only short-cut.
228 Other modules do not use this mechanism for checking roles, although
229 you can use the "Class::DOES" module from the CPAN to allow it.
230
231 In addition, you must define a "AUTODIE_HINTS" subroutine that returns
232 a hash-reference containing the hints for your subroutines:
233
234 package Your::Module;
235
236 # We can use the Class::DOES from the CPAN to declare adherence
237 # to a role.
238
239 use Class::DOES 'autodie::hints::provider' => 1;
240
241 # Alternatively, we can declare the role in %DOES. Note that
242 # this is an autodie specific optimisation, although Class::DOES
243 # can be used to promote this to a true role declaration.
244
245 our %DOES = ( 'autodie::hints::provider' => 1 );
246
247 # Finally, we must define the hints themselves.
248
249 sub AUTODIE_HINTS {
250 return {
251 foo => { scalar => HINTS, list => SOME_HINTS },
252 bar => { scalar => HINTS, list => MORE_HINTS },
253 baz => { fail => HINTS },
254 }
255 }
256
257 This allows your code to set hints without relying on "autodie" and
258 "autodie::hints" being loaded, or even installed. In this way your
259 code can do the right thing when "autodie" is installed, but does not
260 need to depend upon it to function.
261
263 When a user-defined subroutine is wrapped by "autodie", it will use
264 hints if they are available, and otherwise reverts to the default
265 behaviour described in the introduction of this document. This can be
266 problematic if we expect a hint to exist, but (for whatever reason) it
267 has not been loaded.
268
269 We can ask autodie to insist that a hint be used by prefixing an
270 exclamation mark to the start of the subroutine name. A lone
271 exclamation mark indicates that all subroutines after it must have
272 hints declared.
273
274 # foo() and bar() must have their hints defined
275 use autodie qw( !foo !bar baz );
276
277 # Everything must have hints (recommended).
278 use autodie qw( ! foo bar baz );
279
280 # bar() and baz() must have their hints defined
281 use autodie qw( foo ! bar baz );
282
283 # Enable autodie for all of Perl's supported built-ins,
284 # as well as for foo(), bar() and baz(). Everything must
285 # have hints.
286 use autodie qw( ! :all foo bar baz );
287
288 If hints are not available for the specified subroutines, this will
289 cause a compile-time error. Insisting on hints for Perl's built-in
290 functions (eg, "open" and "close") is always successful.
291
292 Insisting on hints is strongly recommended.
293
295 Attempts to set_hints_for unidentifiable subroutine
296 You've called "autodie::hints->set_hints_for()" using a subroutine
297 reference, but that reference could not be resolved back to a
298 subroutine name. It may be an anonymous subroutine (which can't be
299 made autodying), or may lack a name for other reasons.
300
301 If you receive this error with a subroutine that has a real name,
302 then you may have found a bug in autodie. See "BUGS" in autodie
303 for how to report this.
304
305 fail hints cannot be provided with either scalar or list hints for %s
306 When defining hints, you can either supply both "list" and "scalar"
307 keywords, or you can provide a single "fail" keyword. You can't
308 mix and match them.
309
310 %s hint missing for %s
311 You've provided either a "scalar" hint without supplying a "list"
312 hint, or vice-versa. You must supply both "scalar" and "list"
313 hints, or a single "fail" hint.
314
316 · Dr Damian Conway for suggesting the hinting interface and providing
317 the example usage.
318
319 · Jacinta Richardson for translating much of my ideas into this
320 documentation.
321
323 Copyright 2009, Paul Fenwick <pjf@perltraining.com.au>
324
326 This module is free software. You may distribute it under the same
327 terms as Perl itself.
328
330 autodie, Class::DOES
331
332
333
334perl v5.28.0 2015-07-09 autodie::hints(3)