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