| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package autodie::hints; |
|
2
|
|
|
|
|
|
|
|
|
3
|
12
|
|
|
12
|
|
1758
|
use strict; |
|
|
12
|
|
|
|
|
18
|
|
|
|
12
|
|
|
|
|
483
|
|
|
4
|
12
|
|
|
12
|
|
62
|
use warnings; |
|
|
12
|
|
|
|
|
19
|
|
|
|
12
|
|
|
|
|
565
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
12
|
|
|
12
|
|
52
|
use constant PERL58 => ( $] < 5.009 ); |
|
|
12
|
|
|
|
|
17
|
|
|
|
12
|
|
|
|
|
2205
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '2.27'; # 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
|
|
56
|
use constant UNDEF_ONLY => sub { not defined $_[0] }; |
|
|
12
|
|
|
|
|
16
|
|
|
|
12
|
|
|
|
|
854
|
|
|
|
0
|
|
|
|
|
0
|
|
|
329
|
|
|
|
|
|
|
use constant EMPTY_OR_UNDEF => sub { |
|
330
|
0
|
0
|
0
|
|
|
0
|
! @_ or |
|
331
|
|
|
|
|
|
|
@_==1 && !defined $_[0] |
|
332
|
12
|
|
|
12
|
|
55
|
}; |
|
|
12
|
|
|
|
|
14
|
|
|
|
12
|
|
|
|
|
782
|
|
|
333
|
|
|
|
|
|
|
|
|
334
|
12
|
|
|
12
|
|
52
|
use constant EMPTY_ONLY => sub { @_ == 0 }; |
|
|
12
|
|
|
|
|
17
|
|
|
|
12
|
|
|
|
|
859
|
|
|
|
0
|
|
|
|
|
0
|
|
|
335
|
|
|
|
|
|
|
use constant EMPTY_OR_FALSE => sub { |
|
336
|
0
|
0
|
0
|
|
|
0
|
! @_ or |
|
337
|
|
|
|
|
|
|
@_==1 && !$_[0] |
|
338
|
12
|
|
|
12
|
|
54
|
}; |
|
|
12
|
|
|
|
|
13
|
|
|
|
12
|
|
|
|
|
792
|
|
|
339
|
|
|
|
|
|
|
|
|
340
|
12
|
50
|
|
12
|
|
52
|
use constant SINGLE_TRUE => sub { @_ == 1 and not $_[0] }; |
|
|
12
|
|
|
|
|
19
|
|
|
|
12
|
|
|
|
|
775
|
|
|
|
7
|
|
|
|
|
161
|
|
|
341
|
|
|
|
|
|
|
|
|
342
|
12
|
|
|
|
|
645
|
use constant DEFAULT_HINTS => { |
|
343
|
|
|
|
|
|
|
scalar => UNDEF_ONLY, |
|
344
|
|
|
|
|
|
|
list => EMPTY_OR_UNDEF, |
|
345
|
12
|
|
|
12
|
|
50
|
}; |
|
|
12
|
|
|
|
|
33
|
|
|
346
|
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
|
|
348
|
12
|
|
|
12
|
|
65
|
use constant HINTS_PROVIDER => 'autodie::hints::provider'; |
|
|
12
|
|
|
|
|
13
|
|
|
|
12
|
|
|
|
|
2432
|
|
|
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
|
|
|
|
|
19
|
|
|
|
12
|
|
|
|
|
3669
|
|
|
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
|
964
|
return join( '::', get_code_info( $_[1] ) ); |
|
391
|
|
|
|
|
|
|
} |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
my %Hints_loaded = (); |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
sub load_hints { |
|
396
|
30
|
|
|
30
|
0
|
40
|
my ($class, $sub) = @_; |
|
397
|
|
|
|
|
|
|
|
|
398
|
30
|
|
|
|
|
170
|
my ($package) = ( $sub =~ /(.*)::/ ); |
|
399
|
|
|
|
|
|
|
|
|
400
|
30
|
50
|
|
|
|
76
|
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
|
|
|
|
128
|
return if $Hints_loaded{$package}++; |
|
410
|
|
|
|
|
|
|
|
|
411
|
9
|
|
|
|
|
17
|
my $hints_available = 0; |
|
412
|
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
{ |
|
414
|
12
|
|
|
12
|
|
64
|
no strict 'refs'; ## no critic |
|
|
12
|
|
|
|
|
14
|
|
|
|
12
|
|
|
|
|
7148
|
|
|
|
9
|
|
|
|
|
15
|
|
|
415
|
|
|
|
|
|
|
|
|
416
|
9
|
100
|
66
|
|
|
224
|
if ($package->can('DOES') and $package->DOES(HINTS_PROVIDER) ) { |
|
|
|
100
|
|
|
|
|
|
|
417
|
3
|
|
|
|
|
29
|
$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
|
|
|
|
39
|
return if not $hints_available; |
|
428
|
|
|
|
|
|
|
|
|
429
|
5
|
|
|
|
|
7
|
my %package_hints = %{ $package->AUTODIE_HINTS }; |
|
|
5
|
|
|
|
|
24
|
|
|
430
|
|
|
|
|
|
|
|
|
431
|
5
|
|
|
|
|
126
|
foreach my $sub (keys %package_hints) { |
|
432
|
|
|
|
|
|
|
|
|
433
|
15
|
|
|
|
|
35
|
my $hint = $package_hints{$sub}; |
|
434
|
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
# Ensure we have a package name. |
|
436
|
15
|
50
|
|
|
|
60
|
$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
|
|
|
|
|
70
|
$class->normalise_hints(\%Hints, $sub); |
|
442
|
|
|
|
|
|
|
} |
|
443
|
|
|
|
|
|
|
|
|
444
|
5
|
|
|
|
|
20
|
return; |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
} |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
sub normalise_hints { |
|
449
|
24
|
|
|
24
|
0
|
35
|
my ($class, $hints, $sub) = @_; |
|
450
|
|
|
|
|
|
|
|
|
451
|
24
|
100
|
|
|
|
60
|
if ( exists $hints->{$sub}->{fail} ) { |
|
452
|
|
|
|
|
|
|
|
|
453
|
6
|
50
|
33
|
|
|
59
|
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
|
|
|
|
|
634
|
$hints->{$sub}->{scalar} = |
|
465
|
|
|
|
|
|
|
$hints->{$sub}->{list} = delete $hints->{$sub}->{fail}; |
|
466
|
|
|
|
|
|
|
|
|
467
|
6
|
|
|
|
|
56
|
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
|
|
|
|
97
|
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
|
|
|
|
|
36
|
return; |
|
483
|
|
|
|
|
|
|
} |
|
484
|
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
sub get_hints_for { |
|
486
|
89
|
|
|
89
|
0
|
129
|
my ($class, $sub) = @_; |
|
487
|
|
|
|
|
|
|
|
|
488
|
89
|
|
|
|
|
178
|
my $subname = $class->sub_fullname( $sub ); |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
# If we have hints loaded for a sub, then return them. |
|
491
|
|
|
|
|
|
|
|
|
492
|
89
|
100
|
|
|
|
254
|
if ( exists $Hints{ $subname } ) { |
|
493
|
59
|
|
|
|
|
171
|
return $Hints{ $subname }; |
|
494
|
|
|
|
|
|
|
} |
|
495
|
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
# If not, we try to load them... |
|
497
|
|
|
|
|
|
|
|
|
498
|
30
|
|
|
|
|
70
|
$class->load_hints( $subname ); |
|
499
|
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
# ...and try again! |
|
501
|
|
|
|
|
|
|
|
|
502
|
30
|
100
|
|
|
|
65
|
if ( exists $Hints{ $subname } ) { |
|
503
|
5
|
|
|
|
|
21
|
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
|
|
|
|
|
69
|
return; |
|
510
|
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
} |
|
512
|
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
sub set_hints_for { |
|
514
|
9
|
|
|
9
|
1
|
48814
|
my ($class, $sub, $hints) = @_; |
|
515
|
|
|
|
|
|
|
|
|
516
|
9
|
100
|
|
|
|
23
|
if (ref $sub) { |
|
517
|
8
|
|
|
|
|
16
|
$sub = $class->sub_fullname( $sub ); |
|
518
|
|
|
|
|
|
|
|
|
519
|
8
|
|
|
|
|
27
|
require Carp; |
|
520
|
|
|
|
|
|
|
|
|
521
|
8
|
50
|
|
|
|
17
|
$sub or Carp::croak("Attempts to set_hints_for unidentifiable subroutine"); |
|
522
|
|
|
|
|
|
|
} |
|
523
|
|
|
|
|
|
|
|
|
524
|
9
|
50
|
|
|
|
19
|
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
|
|
|
|
|
17
|
$class->normalise_hints(\%Hints, $sub); |
|
531
|
|
|
|
|
|
|
|
|
532
|
9
|
|
|
|
|
14
|
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 |