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 subroutine references, objects overloading smart-
94 match, regular expressions, and depending on Perl version possibly
95 other things. You can specify different hints for how failure should
96 be identified in scalar and list contexts.
97
98 These examples apply for use in the "AUTODIE_HINTS" subroutine and when
99 calling "autodie::hints->set_hints_for()".
100
101 The most common context-specific hints are:
102
103 # Scalar failures always return undef:
104 { scalar => sub { !defined($_[0]) } }
105
106 # Scalar failures return any false value [default expectation]:
107 { scalar => sub { ! $_[0] } }
108
109 # Scalar failures always return zero explicitly:
110 { scalar => sub { defined($_[0]) && $_[0] eq '0' } }
111
112 # List failures always return an empty list:
113 { list => sub { !@_ } }
114
115 # List failures return () or (undef) [default expectation]:
116 { list => sub { ! @_ || @_ == 1 && !defined $_[0] } }
117
118 # List failures return () or a single false value:
119 { list => sub { ! @_ || @_ == 1 && !$_[0] } }
120
121 # List failures return (undef, "some string")
122 { list => sub { @_ == 2 && !defined $_[0] } }
123
124 # Unsuccessful foo() returns 'FAIL' or '_FAIL' in scalar context,
125 # returns (-1) in list context...
126 autodie::hints->set_hints_for(
127 \&foo,
128 {
129 scalar => qr/^ _? FAIL $/xms,
130 list => sub { @_ == 1 && $_[0] eq -1 },
131 }
132 );
133
134 # Unsuccessful foo() returns 0 in all contexts...
135 autodie::hints->set_hints_for(
136 \&foo,
137 {
138 scalar => sub { defined($_[0]) && $_[0] == 0 },
139 list => sub { @_ == 1 && defined($_[0]) && $_[0] == 0 },
140 }
141 );
142
143 This "in all contexts" construction is very common, and can be
144 abbreviated, using the 'fail' key. This sets both the "scalar" and
145 "list" hints to the same value:
146
147 # Unsuccessful foo() returns 0 in all contexts...
148 autodie::hints->set_hints_for(
149 \&foo,
150 {
151 fail => sub { @_ == 1 and defined $_[0] and $_[0] == 0 }
152 }
153 );
154
155 # Unsuccessful think_positive() returns negative number on failure...
156 autodie::hints->set_hints_for(
157 \&think_positive,
158 {
159 fail => sub { $_[0] < 0 }
160 }
161 );
162
163 # Unsuccessful my_system() returns non-zero on failure...
164 autodie::hints->set_hints_for(
165 \&my_system,
166 {
167 fail => sub { $_[0] != 0 }
168 }
169 );
170
172 If you are using a module which returns something special on failure,
173 then you can manually create hints for each of the desired subroutines.
174 Once the hints are specified, they are available for all files and
175 modules loaded thereafter, thus you can move this work into a module
176 and it will still work.
177
178 use Some::Module qw(foo bar);
179 use autodie::hints;
180
181 autodie::hints->set_hints_for(
182 \&foo,
183 {
184 scalar => SCALAR_HINT,
185 list => LIST_HINT,
186 }
187 );
188 autodie::hints->set_hints_for(
189 \&bar,
190 { fail => SOME_HINT, }
191 );
192
193 It is possible to pass either a subroutine reference (recommended) or a
194 fully qualified subroutine name as the first argument. This means you
195 can set hints on modules that might get loaded:
196
197 use autodie::hints;
198 autodie::hints->set_hints_for(
199 'Some::Module:bar', { fail => SCALAR_HINT, }
200 );
201
202 This technique is most useful when you have a project that uses a lot
203 of third-party modules. You can define all your possible hints in one-
204 place. This can even be in a sub-class of autodie. For example:
205
206 package my::autodie;
207
208 use parent qw(autodie);
209 use autodie::hints;
210
211 autodie::hints->set_hints_for(...);
212
213 1;
214
215 You can now "use my::autodie", which will work just like the standard
216 "autodie", but is now aware of any hints that you've set.
217
219 "autodie" provides a passive interface to allow you to declare hints
220 for your module. These hints will be found and used by "autodie" if it
221 is loaded, but otherwise have no effect (or dependencies) without
222 autodie. To set these, your module needs to declare that it does the
223 "autodie::hints::provider" role. This can be done by writing your own
224 "DOES" method, using a system such as "Class::DOES" to handle the
225 heavy-lifting for you, or declaring a %DOES package variable with a
226 "autodie::hints::provider" key and a corresponding true value.
227
228 Note that checking for a %DOES hash is an "autodie"-only short-cut.
229 Other modules do not use this mechanism for checking roles, although
230 you can use the "Class::DOES" module from the CPAN to allow it.
231
232 In addition, you must define a "AUTODIE_HINTS" subroutine that returns
233 a hash-reference containing the hints for your subroutines:
234
235 package Your::Module;
236
237 # We can use the Class::DOES from the CPAN to declare adherence
238 # to a role.
239
240 use Class::DOES 'autodie::hints::provider' => 1;
241
242 # Alternatively, we can declare the role in %DOES. Note that
243 # this is an autodie specific optimisation, although Class::DOES
244 # can be used to promote this to a true role declaration.
245
246 our %DOES = ( 'autodie::hints::provider' => 1 );
247
248 # Finally, we must define the hints themselves.
249
250 sub AUTODIE_HINTS {
251 return {
252 foo => { scalar => HINTS, list => SOME_HINTS },
253 bar => { scalar => HINTS, list => MORE_HINTS },
254 baz => { fail => HINTS },
255 }
256 }
257
258 This allows your code to set hints without relying on "autodie" and
259 "autodie::hints" being loaded, or even installed. In this way your
260 code can do the right thing when "autodie" is installed, but does not
261 need to depend upon it to function.
262
264 When a user-defined subroutine is wrapped by "autodie", it will use
265 hints if they are available, and otherwise reverts to the default
266 behaviour described in the introduction of this document. This can be
267 problematic if we expect a hint to exist, but (for whatever reason) it
268 has not been loaded.
269
270 We can ask autodie to insist that a hint be used by prefixing an
271 exclamation mark to the start of the subroutine name. A lone
272 exclamation mark indicates that all subroutines after it must have
273 hints declared.
274
275 # foo() and bar() must have their hints defined
276 use autodie qw( !foo !bar baz );
277
278 # Everything must have hints (recommended).
279 use autodie qw( ! foo bar baz );
280
281 # bar() and baz() must have their hints defined
282 use autodie qw( foo ! bar baz );
283
284 # Enable autodie for all of Perl's supported built-ins,
285 # as well as for foo(), bar() and baz(). Everything must
286 # have hints.
287 use autodie qw( ! :all foo bar baz );
288
289 If hints are not available for the specified subroutines, this will
290 cause a compile-time error. Insisting on hints for Perl's built-in
291 functions (eg, "open" and "close") is always successful.
292
293 Insisting on hints is strongly recommended.
294
296 Attempts to set_hints_for unidentifiable subroutine
297 You've called "autodie::hints->set_hints_for()" using a subroutine
298 reference, but that reference could not be resolved back to a
299 subroutine name. It may be an anonymous subroutine (which can't be
300 made autodying), or may lack a name for other reasons.
301
302 If you receive this error with a subroutine that has a real name,
303 then you may have found a bug in autodie. See "BUGS" in autodie
304 for how to report this.
305
306 fail hints cannot be provided with either scalar or list hints for %s
307 When defining hints, you can either supply both "list" and "scalar"
308 keywords, or you can provide a single "fail" keyword. You can't
309 mix and match them.
310
311 %s hint missing for %s
312 You've provided either a "scalar" hint without supplying a "list"
313 hint, or vice-versa. You must supply both "scalar" and "list"
314 hints, or a single "fail" hint.
315
317 • Dr Damian Conway for suggesting the hinting interface and providing
318 the example usage.
319
320 • Jacinta Richardson for translating much of my ideas into this
321 documentation.
322
324 Copyright 2009, Paul Fenwick <pjf@perltraining.com.au>
325
327 This module is free software. You may distribute it under the same
328 terms as Perl itself.
329
331 autodie, Class::DOES
332
333
334
335perl v5.32.1 2021-01-27 autodie::hints(3)