line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package autodie::hints; |
2
|
|
|
|
|
|
|
|
3
|
12
|
|
|
12
|
|
1578
|
use strict; |
|
12
|
|
|
|
|
17
|
|
|
12
|
|
|
|
|
489
|
|
4
|
12
|
|
|
12
|
|
53
|
use warnings; |
|
12
|
|
|
|
|
16
|
|
|
12
|
|
|
|
|
453
|
|
5
|
|
|
|
|
|
|
|
6
|
12
|
|
|
12
|
|
46
|
use constant PERL58 => ( $] < 5.009 ); |
|
12
|
|
|
|
|
15
|
|
|
12
|
|
|
|
|
1949
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '2.29'; # VERSION: Generated by DZP::OurPkg:Version |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
# ABSTRACT: Provide hints about user subroutines to autodie |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
autodie::hints - Provide hints about user subroutines to autodie |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 SYNOPSIS |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
package Your::Module; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our %DOES = ( 'autodie::hints::provider' => 1 ); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub AUTODIE_HINTS { |
23
|
|
|
|
|
|
|
return { |
24
|
|
|
|
|
|
|
foo => { scalar => HINTS, list => SOME_HINTS }, |
25
|
|
|
|
|
|
|
bar => { scalar => HINTS, list => MORE_HINTS }, |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
} |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
# Later, in your main program... |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
use Your::Module qw(foo bar); |
32
|
|
|
|
|
|
|
use autodie qw(:default foo bar); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
foo(); # succeeds or dies based on scalar hints |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# Alternatively, hints can be set on subroutines we've |
37
|
|
|
|
|
|
|
# imported. |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
use autodie::hints; |
40
|
|
|
|
|
|
|
use Some::Module qw(think_positive); |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
BEGIN { |
43
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
44
|
|
|
|
|
|
|
\&think_positive, |
45
|
|
|
|
|
|
|
{ |
46
|
|
|
|
|
|
|
fail => sub { $_[0] <= 0 } |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
) |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
use autodie qw(think_positive); |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
think_positive(...); # Returns positive or dies. |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
=head1 DESCRIPTION |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head2 Introduction |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
The L<autodie> pragma is very smart when it comes to working with |
60
|
|
|
|
|
|
|
Perl's built-in functions. The behaviour for these functions are |
61
|
|
|
|
|
|
|
fixed, and C<autodie> knows exactly how they try to signal failure. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
But what about user-defined subroutines from modules? If you use |
64
|
|
|
|
|
|
|
C<autodie> on a user-defined subroutine then it assumes the following |
65
|
|
|
|
|
|
|
behaviour to demonstrate failure: |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=over |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
=item * |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
A false value, in scalar context |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=item * |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
An empty list, in list context |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=item * |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
A list containing a single undef, in list context |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=back |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
All other return values (including the list of the single zero, and the |
84
|
|
|
|
|
|
|
list containing a single empty string) are considered successful. However, |
85
|
|
|
|
|
|
|
real-world code isn't always that easy. Perhaps the code you're working |
86
|
|
|
|
|
|
|
with returns a string containing the word "FAIL" upon failure, or a |
87
|
|
|
|
|
|
|
two element list containing C<(undef, "human error message")>. To make |
88
|
|
|
|
|
|
|
autodie work with these sorts of subroutines, we have |
89
|
|
|
|
|
|
|
the I<hinting interface>. |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
The hinting interface allows I<hints> to be provided to C<autodie> |
92
|
|
|
|
|
|
|
on how it should detect failure from user-defined subroutines. While |
93
|
|
|
|
|
|
|
these I<can> be provided by the end-user of C<autodie>, they are ideally |
94
|
|
|
|
|
|
|
written into the module itself, or into a helper module or sub-class |
95
|
|
|
|
|
|
|
of C<autodie> itself. |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=head2 What are hints? |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
A I<hint> is a subroutine or value that is checked against the |
100
|
|
|
|
|
|
|
return value of an autodying subroutine. If the match returns true, |
101
|
|
|
|
|
|
|
C<autodie> considers the subroutine to have failed. |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
If the hint provided is a subroutine, then C<autodie> will pass |
104
|
|
|
|
|
|
|
the complete return value to that subroutine. If the hint is |
105
|
|
|
|
|
|
|
any other value, then C<autodie> will smart-match against the |
106
|
|
|
|
|
|
|
value provided. In Perl 5.8.x there is no smart-match operator, and as such |
107
|
|
|
|
|
|
|
only subroutine hints are supported in these versions. |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
Hints can be provided for both scalar and list contexts. Note |
110
|
|
|
|
|
|
|
that an autodying subroutine will never see a void context, as |
111
|
|
|
|
|
|
|
C<autodie> always needs to capture the return value for examination. |
112
|
|
|
|
|
|
|
Autodying subroutines called in void context act as if they're called |
113
|
|
|
|
|
|
|
in a scalar context, but their return value is discarded after it |
114
|
|
|
|
|
|
|
has been checked. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=head2 Example hints |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
Hints may consist of scalars, array references, regular expressions and |
119
|
|
|
|
|
|
|
subroutine references. You can specify different hints for how |
120
|
|
|
|
|
|
|
failure should be identified in scalar and list contexts. |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
These examples apply for use in the C<AUTODIE_HINTS> subroutine and when |
123
|
|
|
|
|
|
|
calling C<autodie::hints->set_hints_for()>. |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
The most common context-specific hints are: |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# Scalar failures always return undef: |
128
|
|
|
|
|
|
|
{ scalar => undef } |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# Scalar failures return any false value [default expectation]: |
131
|
|
|
|
|
|
|
{ scalar => sub { ! $_[0] } } |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
# Scalar failures always return zero explicitly: |
134
|
|
|
|
|
|
|
{ scalar => '0' } |
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
# List failures always return an empty list: |
137
|
|
|
|
|
|
|
{ list => [] } |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
# List failures return () or (undef) [default expectation]: |
140
|
|
|
|
|
|
|
{ list => sub { ! @_ || @_ == 1 && !defined $_[0] } } |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# List failures return () or a single false value: |
143
|
|
|
|
|
|
|
{ list => sub { ! @_ || @_ == 1 && !$_[0] } } |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
# List failures return (undef, "some string") |
146
|
|
|
|
|
|
|
{ list => sub { @_ == 2 && !defined $_[0] } } |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# Unsuccessful foo() returns 'FAIL' or '_FAIL' in scalar context, |
149
|
|
|
|
|
|
|
# returns (-1) in list context... |
150
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
151
|
|
|
|
|
|
|
\&foo, |
152
|
|
|
|
|
|
|
{ |
153
|
|
|
|
|
|
|
scalar => qr/^ _? FAIL $/xms, |
154
|
|
|
|
|
|
|
list => [-1], |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
); |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Unsuccessful foo() returns 0 in all contexts... |
159
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
160
|
|
|
|
|
|
|
\&foo, |
161
|
|
|
|
|
|
|
{ |
162
|
|
|
|
|
|
|
scalar => 0, |
163
|
|
|
|
|
|
|
list => [0], |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
); |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
This "in all contexts" construction is very common, and can be |
168
|
|
|
|
|
|
|
abbreviated, using the 'fail' key. This sets both the C<scalar> |
169
|
|
|
|
|
|
|
and C<list> hints to the same value: |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
# Unsuccessful foo() returns 0 in all contexts... |
172
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
173
|
|
|
|
|
|
|
\&foo, |
174
|
|
|
|
|
|
|
{ |
175
|
|
|
|
|
|
|
fail => sub { @_ == 1 and defined $_[0] and $_[0] == 0 } |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
); |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
# Unsuccessful think_positive() returns negative number on failure... |
180
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
181
|
|
|
|
|
|
|
\&think_positive, |
182
|
|
|
|
|
|
|
{ |
183
|
|
|
|
|
|
|
fail => sub { $_[0] < 0 } |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
); |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# Unsuccessful my_system() returns non-zero on failure... |
188
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
189
|
|
|
|
|
|
|
\&my_system, |
190
|
|
|
|
|
|
|
{ |
191
|
|
|
|
|
|
|
fail => sub { $_[0] != 0 } |
192
|
|
|
|
|
|
|
} |
193
|
|
|
|
|
|
|
); |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head1 Manually setting hints from within your program |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
If you are using a module which returns something special on failure, then |
198
|
|
|
|
|
|
|
you can manually create hints for each of the desired subroutines. Once |
199
|
|
|
|
|
|
|
the hints are specified, they are available for all files and modules loaded |
200
|
|
|
|
|
|
|
thereafter, thus you can move this work into a module and it will still |
201
|
|
|
|
|
|
|
work. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
use Some::Module qw(foo bar); |
204
|
|
|
|
|
|
|
use autodie::hints; |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
207
|
|
|
|
|
|
|
\&foo, |
208
|
|
|
|
|
|
|
{ |
209
|
|
|
|
|
|
|
scalar => SCALAR_HINT, |
210
|
|
|
|
|
|
|
list => LIST_HINT, |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
); |
213
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
214
|
|
|
|
|
|
|
\&bar, |
215
|
|
|
|
|
|
|
{ fail => SOME_HINT, } |
216
|
|
|
|
|
|
|
); |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
It is possible to pass either a subroutine reference (recommended) or a fully |
219
|
|
|
|
|
|
|
qualified subroutine name as the first argument. This means you can set hints |
220
|
|
|
|
|
|
|
on modules that I<might> get loaded: |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
use autodie::hints; |
223
|
|
|
|
|
|
|
autodie::hints->set_hints_for( |
224
|
|
|
|
|
|
|
'Some::Module:bar', { fail => SCALAR_HINT, } |
225
|
|
|
|
|
|
|
); |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
This technique is most useful when you have a project that uses a |
228
|
|
|
|
|
|
|
lot of third-party modules. You can define all your possible hints |
229
|
|
|
|
|
|
|
in one-place. This can even be in a sub-class of autodie. For |
230
|
|
|
|
|
|
|
example: |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
package my::autodie; |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
use parent qw(autodie); |
235
|
|
|
|
|
|
|
use autodie::hints; |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
autodie::hints->set_hints_for(...); |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
1; |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
You can now C<use my::autodie>, which will work just like the standard |
242
|
|
|
|
|
|
|
C<autodie>, but is now aware of any hints that you've set. |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=head1 Adding hints to your module |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
C<autodie> provides a passive interface to allow you to declare hints for |
247
|
|
|
|
|
|
|
your module. These hints will be found and used by C<autodie> if it |
248
|
|
|
|
|
|
|
is loaded, but otherwise have no effect (or dependencies) without autodie. |
249
|
|
|
|
|
|
|
To set these, your module needs to declare that it I<does> the |
250
|
|
|
|
|
|
|
C<autodie::hints::provider> role. This can be done by writing your |
251
|
|
|
|
|
|
|
own C<DOES> method, using a system such as C<Class::DOES> to handle |
252
|
|
|
|
|
|
|
the heavy-lifting for you, or declaring a C<%DOES> package variable |
253
|
|
|
|
|
|
|
with a C<autodie::hints::provider> key and a corresponding true value. |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
Note that checking for a C<%DOES> hash is an C<autodie>-only |
256
|
|
|
|
|
|
|
short-cut. Other modules do not use this mechanism for checking |
257
|
|
|
|
|
|
|
roles, although you can use the C<Class::DOES> module from the |
258
|
|
|
|
|
|
|
CPAN to allow it. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
In addition, you must define a C<AUTODIE_HINTS> subroutine that returns |
261
|
|
|
|
|
|
|
a hash-reference containing the hints for your subroutines: |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
package Your::Module; |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
# We can use the Class::DOES from the CPAN to declare adherence |
266
|
|
|
|
|
|
|
# to a role. |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
use Class::DOES 'autodie::hints::provider' => 1; |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
# Alternatively, we can declare the role in %DOES. Note that |
271
|
|
|
|
|
|
|
# this is an autodie specific optimisation, although Class::DOES |
272
|
|
|
|
|
|
|
# can be used to promote this to a true role declaration. |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
our %DOES = ( 'autodie::hints::provider' => 1 ); |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
# Finally, we must define the hints themselves. |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub AUTODIE_HINTS { |
279
|
|
|
|
|
|
|
return { |
280
|
|
|
|
|
|
|
foo => { scalar => HINTS, list => SOME_HINTS }, |
281
|
|
|
|
|
|
|
bar => { scalar => HINTS, list => MORE_HINTS }, |
282
|
|
|
|
|
|
|
baz => { fail => HINTS }, |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
This allows your code to set hints without relying on C<autodie> and |
287
|
|
|
|
|
|
|
C<autodie::hints> being loaded, or even installed. In this way your |
288
|
|
|
|
|
|
|
code can do the right thing when C<autodie> is installed, but does not |
289
|
|
|
|
|
|
|
need to depend upon it to function. |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=head1 Insisting on hints |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
When a user-defined subroutine is wrapped by C<autodie>, it will |
294
|
|
|
|
|
|
|
use hints if they are available, and otherwise reverts to the |
295
|
|
|
|
|
|
|
I<default behaviour> described in the introduction of this document. |
296
|
|
|
|
|
|
|
This can be problematic if we expect a hint to exist, but (for |
297
|
|
|
|
|
|
|
whatever reason) it has not been loaded. |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
We can ask autodie to I<insist> that a hint be used by prefixing |
300
|
|
|
|
|
|
|
an exclamation mark to the start of the subroutine name. A lone |
301
|
|
|
|
|
|
|
exclamation mark indicates that I<all> subroutines after it must |
302
|
|
|
|
|
|
|
have hints declared. |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
# foo() and bar() must have their hints defined |
305
|
|
|
|
|
|
|
use autodie qw( !foo !bar baz ); |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
# Everything must have hints (recommended). |
308
|
|
|
|
|
|
|
use autodie qw( ! foo bar baz ); |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
# bar() and baz() must have their hints defined |
311
|
|
|
|
|
|
|
use autodie qw( foo ! bar baz ); |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
# Enable autodie for all of Perl's supported built-ins, |
314
|
|
|
|
|
|
|
# as well as for foo(), bar() and baz(). Everything must |
315
|
|
|
|
|
|
|
# have hints. |
316
|
|
|
|
|
|
|
use autodie qw( ! :all foo bar baz ); |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
If hints are not available for the specified subroutines, this will cause a |
319
|
|
|
|
|
|
|
compile-time error. Insisting on hints for Perl's built-in functions |
320
|
|
|
|
|
|
|
(eg, C<open> and C<close>) is always successful. |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
Insisting on hints is I<strongly> recommended. |
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=cut |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
# TODO: implement regular expression hints |
327
|
|
|
|
|
|
|
|
328
|
12
|
|
|
12
|
|
60
|
use constant UNDEF_ONLY => sub { not defined $_[0] }; |
|
12
|
|
|
|
|
16
|
|
|
12
|
|
|
|
|
834
|
|
|
0
|
|
|
|
|
0
|
|
329
|
|
|
|
|
|
|
use constant EMPTY_OR_UNDEF => sub { |
330
|
0
|
0
|
0
|
|
|
0
|
! @_ or |
331
|
|
|
|
|
|
|
@_==1 && !defined $_[0] |
332
|
12
|
|
|
12
|
|
52
|
}; |
|
12
|
|
|
|
|
21
|
|
|
12
|
|
|
|
|
703
|
|
333
|
|
|
|
|
|
|
|
334
|
12
|
|
|
12
|
|
52
|
use constant EMPTY_ONLY => sub { @_ == 0 }; |
|
12
|
|
|
|
|
21
|
|
|
12
|
|
|
|
|
782
|
|
|
0
|
|
|
|
|
0
|
|
335
|
|
|
|
|
|
|
use constant EMPTY_OR_FALSE => sub { |
336
|
0
|
0
|
0
|
|
|
0
|
! @_ or |
337
|
|
|
|
|
|
|
@_==1 && !$_[0] |
338
|
12
|
|
|
12
|
|
59
|
}; |
|
12
|
|
|
|
|
14
|
|
|
12
|
|
|
|
|
832
|
|
339
|
|
|
|
|
|
|
|
340
|
12
|
50
|
|
12
|
|
54
|
use constant SINGLE_TRUE => sub { @_ == 1 and not $_[0] }; |
|
12
|
|
|
|
|
22
|
|
|
12
|
|
|
|
|
815
|
|
|
7
|
|
|
|
|
205
|
|
341
|
|
|
|
|
|
|
|
342
|
12
|
|
|
|
|
642
|
use constant DEFAULT_HINTS => { |
343
|
|
|
|
|
|
|
scalar => UNDEF_ONLY, |
344
|
|
|
|
|
|
|
list => EMPTY_OR_UNDEF, |
345
|
12
|
|
|
12
|
|
63
|
}; |
|
12
|
|
|
|
|
19
|
|
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
|
348
|
12
|
|
|
12
|
|
64
|
use constant HINTS_PROVIDER => 'autodie::hints::provider'; |
|
12
|
|
|
|
|
19
|
|
|
12
|
|
|
|
|
2594
|
|
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
our $DEBUG = 0; |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
# Only ( undef ) is a strange but possible situation for very |
353
|
|
|
|
|
|
|
# badly written code. It's not supported yet. |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
my %Hints = ( |
356
|
|
|
|
|
|
|
'File::Copy::copy' => { scalar => SINGLE_TRUE, list => SINGLE_TRUE }, |
357
|
|
|
|
|
|
|
'File::Copy::move' => { scalar => SINGLE_TRUE, list => SINGLE_TRUE }, |
358
|
|
|
|
|
|
|
'File::Copy::cp' => { scalar => SINGLE_TRUE, list => SINGLE_TRUE }, |
359
|
|
|
|
|
|
|
'File::Copy::mv' => { scalar => SINGLE_TRUE, list => SINGLE_TRUE }, |
360
|
|
|
|
|
|
|
); |
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
# Start by using Sub::Identify if it exists on this system. |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
eval { require Sub::Identify; Sub::Identify->import('get_code_info'); }; |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
# If it doesn't exist, we'll define our own. This code is directly |
367
|
|
|
|
|
|
|
# taken from Rafael Garcia's Sub::Identify 0.04, used under the same |
368
|
|
|
|
|
|
|
# license as Perl itself. |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
if ($@) { |
371
|
|
|
|
|
|
|
require B; |
372
|
|
|
|
|
|
|
|
373
|
12
|
|
|
12
|
|
55
|
no warnings 'once'; |
|
12
|
|
|
|
|
15
|
|
|
12
|
|
|
|
|
2977
|
|
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
*get_code_info = sub ($) { |
376
|
|
|
|
|
|
|
|
377
|
|
|
|
|
|
|
my ($coderef) = @_; |
378
|
|
|
|
|
|
|
ref $coderef or return; |
379
|
|
|
|
|
|
|
my $cv = B::svref_2object($coderef); |
380
|
|
|
|
|
|
|
$cv->isa('B::CV') or return; |
381
|
|
|
|
|
|
|
# bail out if GV is undefined |
382
|
|
|
|
|
|
|
$cv->GV->isa('B::SPECIAL') and return; |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
return ($cv->GV->STASH->NAME, $cv->GV->NAME); |
385
|
|
|
|
|
|
|
}; |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub sub_fullname { |
390
|
143
|
|
|
143
|
0
|
972
|
return join( '::', get_code_info( $_[1] ) ); |
391
|
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
my %Hints_loaded = (); |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
sub load_hints { |
396
|
30
|
|
|
30
|
0
|
35
|
my ($class, $sub) = @_; |
397
|
|
|
|
|
|
|
|
398
|
30
|
|
|
|
|
142
|
my ($package) = ( $sub =~ /(.*)::/ ); |
399
|
|
|
|
|
|
|
|
400
|
30
|
50
|
|
|
|
70
|
if (not defined $package) { |
401
|
0
|
|
|
|
|
0
|
require Carp; |
402
|
0
|
|
|
|
|
0
|
Carp::croak( |
403
|
|
|
|
|
|
|
"Internal error in autodie::hints::load_hints - no package found. |
404
|
|
|
|
|
|
|
"); |
405
|
|
|
|
|
|
|
} |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
# Do nothing if we've already tried to load hints for |
408
|
|
|
|
|
|
|
# this package. |
409
|
30
|
100
|
|
|
|
108
|
return if $Hints_loaded{$package}++; |
410
|
|
|
|
|
|
|
|
411
|
9
|
|
|
|
|
12
|
my $hints_available = 0; |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
{ |
414
|
12
|
|
|
12
|
|
64
|
no strict 'refs'; ## no critic |
|
12
|
|
|
|
|
17
|
|
|
12
|
|
|
|
|
6454
|
|
|
9
|
|
|
|
|
13
|
|
415
|
|
|
|
|
|
|
|
416
|
9
|
100
|
66
|
|
|
208
|
if ($package->can('DOES') and $package->DOES(HINTS_PROVIDER) ) { |
|
|
100
|
|
|
|
|
|
417
|
3
|
|
|
|
|
24
|
$hints_available = 1; |
418
|
|
|
|
|
|
|
} |
419
|
6
|
|
|
|
|
32
|
elsif ( PERL58 and $package->isa(HINTS_PROVIDER) ) { |
420
|
|
|
|
|
|
|
$hints_available = 1; |
421
|
|
|
|
|
|
|
} |
422
|
|
|
|
|
|
|
elsif ( ${"${package}::DOES"}{HINTS_PROVIDER.""} ) { |
423
|
2
|
|
|
|
|
3
|
$hints_available = 1; |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
} |
426
|
|
|
|
|
|
|
|
427
|
9
|
100
|
|
|
|
34
|
return if not $hints_available; |
428
|
|
|
|
|
|
|
|
429
|
5
|
|
|
|
|
11
|
my %package_hints = %{ $package->AUTODIE_HINTS }; |
|
5
|
|
|
|
|
23
|
|
430
|
|
|
|
|
|
|
|
431
|
5
|
|
|
|
|
110
|
foreach my $sub (keys %package_hints) { |
432
|
|
|
|
|
|
|
|
433
|
15
|
|
|
|
|
21
|
my $hint = $package_hints{$sub}; |
434
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
# Ensure we have a package name. |
436
|
15
|
50
|
|
|
|
45
|
$sub = "${package}::$sub" if $sub !~ /::/; |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
# TODO - Currently we don't check for conflicts, should we? |
439
|
15
|
|
|
|
|
27
|
$Hints{$sub} = $hint; |
440
|
|
|
|
|
|
|
|
441
|
15
|
|
|
|
|
876
|
$class->normalise_hints(\%Hints, $sub); |
442
|
|
|
|
|
|
|
} |
443
|
|
|
|
|
|
|
|
444
|
5
|
|
|
|
|
14
|
return; |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
} |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub normalise_hints { |
449
|
24
|
|
|
24
|
0
|
29
|
my ($class, $hints, $sub) = @_; |
450
|
|
|
|
|
|
|
|
451
|
24
|
100
|
|
|
|
58
|
if ( exists $hints->{$sub}->{fail} ) { |
452
|
|
|
|
|
|
|
|
453
|
6
|
50
|
33
|
|
|
28
|
if ( exists $hints->{$sub}->{scalar} or |
454
|
|
|
|
|
|
|
exists $hints->{$sub}->{list} |
455
|
|
|
|
|
|
|
) { |
456
|
|
|
|
|
|
|
# TODO: Turn into a proper diagnostic. |
457
|
0
|
|
|
|
|
0
|
require Carp; |
458
|
0
|
|
|
|
|
0
|
local $Carp::CarpLevel = 1; |
459
|
0
|
|
|
|
|
0
|
Carp::croak("fail hints cannot be provided with either scalar or list hints for $sub"); |
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
# Set our scalar and list hints. |
463
|
|
|
|
|
|
|
|
464
|
6
|
|
|
|
|
14
|
$hints->{$sub}->{scalar} = |
465
|
|
|
|
|
|
|
$hints->{$sub}->{list} = delete $hints->{$sub}->{fail}; |
466
|
|
|
|
|
|
|
|
467
|
6
|
|
|
|
|
12
|
return; |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
} |
470
|
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
# Check to make sure all our hints exist. |
472
|
|
|
|
|
|
|
|
473
|
18
|
|
|
|
|
26
|
foreach my $hint (qw(scalar list)) { |
474
|
36
|
50
|
|
|
|
87
|
if ( not exists $hints->{$sub}->{$hint} ) { |
475
|
|
|
|
|
|
|
# TODO: Turn into a proper diagnostic. |
476
|
0
|
|
|
|
|
0
|
require Carp; |
477
|
0
|
|
|
|
|
0
|
local $Carp::CarpLevel = 1; |
478
|
0
|
|
|
|
|
0
|
Carp::croak("$hint hint missing for $sub"); |
479
|
|
|
|
|
|
|
} |
480
|
|
|
|
|
|
|
} |
481
|
|
|
|
|
|
|
|
482
|
18
|
|
|
|
|
32
|
return; |
483
|
|
|
|
|
|
|
} |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
sub get_hints_for { |
486
|
89
|
|
|
89
|
0
|
103
|
my ($class, $sub) = @_; |
487
|
|
|
|
|
|
|
|
488
|
89
|
|
|
|
|
149
|
my $subname = $class->sub_fullname( $sub ); |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
# If we have hints loaded for a sub, then return them. |
491
|
|
|
|
|
|
|
|
492
|
89
|
100
|
|
|
|
212
|
if ( exists $Hints{ $subname } ) { |
493
|
59
|
|
|
|
|
137
|
return $Hints{ $subname }; |
494
|
|
|
|
|
|
|
} |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
# If not, we try to load them... |
497
|
|
|
|
|
|
|
|
498
|
30
|
|
|
|
|
57
|
$class->load_hints( $subname ); |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
# ...and try again! |
501
|
|
|
|
|
|
|
|
502
|
30
|
100
|
|
|
|
60
|
if ( exists $Hints{ $subname } ) { |
503
|
5
|
|
|
|
|
18
|
return $Hints{ $subname }; |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
# It's the caller's responsibility to use defaults if desired. |
507
|
|
|
|
|
|
|
# This allows on autodie to insist on hints if needed. |
508
|
|
|
|
|
|
|
|
509
|
25
|
|
|
|
|
49
|
return; |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
sub set_hints_for { |
514
|
9
|
|
|
9
|
1
|
46799
|
my ($class, $sub, $hints) = @_; |
515
|
|
|
|
|
|
|
|
516
|
9
|
100
|
|
|
|
23
|
if (ref $sub) { |
517
|
8
|
|
|
|
|
15
|
$sub = $class->sub_fullname( $sub ); |
518
|
|
|
|
|
|
|
|
519
|
8
|
|
|
|
|
26
|
require Carp; |
520
|
|
|
|
|
|
|
|
521
|
8
|
50
|
|
|
|
17
|
$sub or Carp::croak("Attempts to set_hints_for unidentifiable subroutine"); |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
|
524
|
9
|
50
|
|
|
|
17
|
if ($DEBUG) { |
525
|
0
|
|
|
|
|
0
|
warn "autodie::hints: Setting $sub to hints: $hints\n"; |
526
|
|
|
|
|
|
|
} |
527
|
|
|
|
|
|
|
|
528
|
9
|
|
|
|
|
16
|
$Hints{ $sub } = $hints; |
529
|
|
|
|
|
|
|
|
530
|
9
|
|
|
|
|
19
|
$class->normalise_hints(\%Hints, $sub); |
531
|
|
|
|
|
|
|
|
532
|
9
|
|
|
|
|
16
|
return; |
533
|
|
|
|
|
|
|
} |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
1; |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
__END__ |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=head1 Diagnostics |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
=over 4 |
543
|
|
|
|
|
|
|
|
544
|
|
|
|
|
|
|
=item Attempts to set_hints_for unidentifiable subroutine |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
You've called C<< autodie::hints->set_hints_for() >> using a subroutine |
547
|
|
|
|
|
|
|
reference, but that reference could not be resolved back to a |
548
|
|
|
|
|
|
|
subroutine name. It may be an anonymous subroutine (which can't |
549
|
|
|
|
|
|
|
be made autodying), or may lack a name for other reasons. |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
If you receive this error with a subroutine that has a real name, |
552
|
|
|
|
|
|
|
then you may have found a bug in autodie. See L<autodie/BUGS> |
553
|
|
|
|
|
|
|
for how to report this. |
554
|
|
|
|
|
|
|
|
555
|
|
|
|
|
|
|
=item fail hints cannot be provided with either scalar or list hints for %s |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
When defining hints, you can either supply both C<list> and |
558
|
|
|
|
|
|
|
C<scalar> keywords, I<or> you can provide a single C<fail> keyword. |
559
|
|
|
|
|
|
|
You can't mix and match them. |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=item %s hint missing for %s |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
You've provided either a C<scalar> hint without supplying |
564
|
|
|
|
|
|
|
a C<list> hint, or vice-versa. You I<must> supply both C<scalar> |
565
|
|
|
|
|
|
|
and C<list> hints, I<or> a single C<fail> hint. |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=back |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
=over |
572
|
|
|
|
|
|
|
|
573
|
|
|
|
|
|
|
=item * |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
Dr Damian Conway for suggesting the hinting interface and providing the |
576
|
|
|
|
|
|
|
example usage. |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
=item * |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
Jacinta Richardson for translating much of my ideas into this |
581
|
|
|
|
|
|
|
documentation. |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
=back |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
=head1 AUTHOR |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
Copyright 2009, Paul Fenwick E<lt>pjf@perltraining.com.auE<gt> |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
=head1 LICENSE |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
This module is free software. You may distribute it under the |
592
|
|
|
|
|
|
|
same terms as Perl itself. |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
=head1 SEE ALSO |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
L<autodie>, L<Class::DOES> |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
=for Pod::Coverage get_hints_for load_hints normalise_hints sub_fullname get_code_info |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
=cut |