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