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