1 package autodie::hints;
10 autodie::hints - Provide hints about user subroutines to autodie
16 our %DOES = ( 'autodie::hints::provider' => 1 );
20 foo => { scalar => HINTS, list => SOME_HINTS },
21 bar => { scalar => HINTS, list => MORE_HINTS },
25 # Later, in your main program...
27 use Your::Module qw(foo bar);
28 use autodie qw(:default foo bar);
30 foo(); # succeeds or dies based on scalar hints
32 # Alternatively, hints can be set on subroutines we've
36 use Some::Module qw(think_positive);
39 autodie::hints->set_hints_for(
42 fail => sub { $_[0] <= 0 }
46 use autodie qw(think_positive);
48 think_positive(...); # Returns positive or dies.
55 The L<autodie> pragma is very smart when it comes to working with
56 Perl's built-in functions. The behaviour for these functions are
57 fixed, and C<autodie> knows exactly how they try to signal failure.
59 But what about user-defined subroutines from modules? If you use
60 C<autodie> on a user-defined subroutine then it assumes the following
61 behaviour to demonstrate failure:
67 A false value, in scalar context
71 An empty list, in list context
75 A list containing a single undef, in list context
79 All other return values (including the list of the single zero, and the
80 list containing a single empty string) are considered successful. However,
81 real-world code isn't always that easy. Perhaps the code you're working
82 with returns a string containing the word "FAIL" in it upon failure, or a
83 two element list containing C<(undef, "human error message")>. To make
84 autodie work with these sorts of subroutines, we have
85 the I<hinting interface>.
87 The hinting interface allows I<hints> to be provided to C<autodie>
88 on how it should detect failure from user-defined subroutines. While
89 these I<can> be provided by the end-user of C<autodie>, they are ideally
90 written into the module itself, or into a helper module or sub-class
93 =head2 What are hints?
95 A I<hint> is a subroutine or value that is checked against the
96 return value of an autodying subroutine. If the match returns true,
97 C<autodie> considers the subroutine have failed.
99 If the hint provided is a subroutine, then C<autodie> will pass
100 the complete return value to that subroutine. If the hint is
101 any other value, then C<autodie> will smart-match against the
102 value provided. In Perl 5.8.x, there is no smart-match operator, and as such
103 only subroutine hints are supported in these versions.
105 Hints can be provided for both scalar context and list context. Note
106 that an autodying subroutine will never see a void context, as
107 C<autodie> always needs to capture the return value for examination.
108 Autodying subroutines called in void context act as if they're called
109 in a scalar context, but their return value is discarded after it
114 Hints may consist of scalars, array references, regular expressions and
115 subroutine references. You can specify different hints for how
116 failure should be identified in scalar and list contexts.
118 These examples apply for use in the C<AUTODIE_HINTS> subroutine and when
119 calling C<autodie::hints->set_hints_for()>.
121 The most common context-specific hints are:
123 # Scalar failures always return undef:
126 # Scalar failures return any false value [default expectation]:
127 { scalar => sub { ! $_[0] } }
129 # Scalar failures always return zero explicitly:
132 # List failures always return empty list:
135 # List failures return () or (undef) [default expectation]:
136 { list => sub { ! @_ || @_ == 1 && !defined $_[0] } }
138 # List failures return () or a single false value:
139 { list => sub { ! @_ || @_ == 1 && !$_[0] } }
141 # List failures return (undef, "some string")
142 { list => sub { @_ == 2 && !defined $_[0] } }
144 # Unsuccessful foo() returns 'FAIL' or '_FAIL' in scalar context,
145 # returns (-1) in list context...
146 autodie::hints->set_hints_for(
149 scalar => qr/^ _? FAIL $/xms,
154 # Unsuccessful foo() returns 0 in all contexts...
155 autodie::hints->set_hints_for(
163 This "in all contexts" construction is very common, and can be
164 abbreviated, using the 'fail' key. This sets both the C<scalar>
165 and C<list> hints to the same value:
167 # Unsuccessful foo() returns 0 in all contexts...
168 autodie::hints->set_hints_for(
171 fail => sub { @_ == 1 and defined $_[0] and $_[0] == 0 }
175 # Unsuccessful think_positive() returns negative number on failure...
176 autodie::hints->set_hints_for(
179 fail => sub { $_[0] < 0 }
183 # Unsuccessful my_system() returns non-zero on failure...
184 autodie::hints->set_hints_for(
187 fail => sub { $_[0] != 0 }
191 =head1 Manually setting hints from within your program
193 If you are using a module which returns something special on failure, then
194 you can manually create hints for each of the desired subroutines. Once
195 the hints are specified, they are available for all files and modules loaded
196 thereafter, thus you can move this work into a module and it will still
199 use Some::Module qw(foo bar);
202 autodie::hints->set_hints_for(
205 scalar => SCALAR_HINT,
209 autodie::hints->set_hints_for(
211 { fail => SOME_HINT, }
214 It is possible to pass either a subroutine reference (recommended) or a fully
215 qualified subroutine name as the first argument. This means you can set hints
216 on modules that I<might> get loaded:
219 autodie::hints->set_hints_for(
220 'Some::Module:bar', { fail => SCALAR_HINT, }
223 This technique is most useful when you have a project that uses a
224 lot of third-party modules. You can define all your possible hints
225 in one-place. This can even be in a sub-class of autodie. For
230 use parent qw(autodie);
233 autodie::hints->set_hints_for(...);
237 You can now C<use my::autodie>, which will work just like the standard
238 C<autodie>, but is now aware of any hints that you've set.
240 =head1 Adding hints to your module
242 C<autodie> provides a passive interface to allow you to declare hints for
243 your module. These hints will be found and used by C<autodie> if it
244 is loaded, but otherwise have no effect (or dependencies) without autodie.
245 To set these, your module needs to declare that it I<does> the
246 C<autodie::hints::provider> role. This can be done by writing your
247 own C<DOES> method, using a system such as C<Class::DOES> to handle
248 the heavy-lifting for you, or declaring a C<%DOES> package variable
249 with a C<autodie::hints::provider> key and a corresponding true value.
251 Note that checking for a C<%DOES> hash is an C<autodie>-only
252 short-cut. Other modules do not use this mechanism for checking
253 roles, although you can use the C<Class::DOES> module from the
256 In addition, you must define a C<AUTODIE_HINTS> subroutine that returns
257 a hash-reference containing the hints for your subroutines:
259 package Your::Module;
261 # We can use the Class::DOES from the CPAN to declare adherence
264 use Class::DOES 'autodie::hints::provider' => 1;
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.
270 our %DOES = ( 'autodie::hints::provider' => 1 );
272 # Finally, we must define the hints themselves.
276 foo => { scalar => HINTS, list => SOME_HINTS },
277 bar => { scalar => HINTS, list => MORE_HINTS },
278 baz => { fail => HINTS },
282 This allows your code to set hints without relying on C<autodie> and
283 C<autodie::hints> being loaded, or even installed. In this way your
284 code can do the right thing when C<autodie> is installed, but does not
285 need to depend upon it to function.
287 =head1 Insisting on hints
289 When a user-defined subroutine is wrapped by C<autodie>, it will
290 use hints if they are available, and otherwise reverts to the
291 I<default behaviour> described in the introduction of this document.
292 This can be problematic if we expect a hint to exist, but (for
293 whatever reason) it has not been loaded.
295 We can ask autodie to I<insist> that a hint be used by prefixing
296 an exclamation mark to the start of the subroutine name. A lone
297 exclamation mark indicates that I<all> subroutines after it must
300 # foo() and bar() must have their hints defined
301 use autodie qw( !foo !bar baz );
303 # Everything must have hints (recommended).
304 use autodie qw( ! foo bar baz );
306 # bar() and baz() must have their hints defined
307 use autodie qw( foo ! bar baz );
309 # Enable autodie for all of Perl's supported built-ins,
310 # as well as for foo(), bar() and baz(). Everything must
312 use autodie qw( ! :all foo bar baz );
314 If hints are not available for the specified subroutines, this will cause a
315 compile-time error. Insisting on hints for Perl's built-in functions
316 (eg, C<open> and C<close>) is always successful.
318 Insisting on hints is I<strongly> recommended.
322 # TODO: implement regular expression hints
324 use constant UNDEF_ONLY => sub { not defined $_[0] };
325 use constant EMPTY_OR_UNDEF => sub {
327 @_==1 && !defined $_[0]
330 use constant EMPTY_ONLY => sub { @_ == 0 };
331 use constant EMPTY_OR_FALSE => sub {
336 use constant DEFAULT_HINTS => {
337 scalar => UNDEF_ONLY,
338 list => EMPTY_OR_UNDEF,
341 use constant HINTS_PROVIDER => 'autodie::hints::provider';
343 use base qw(Exporter);
347 # Only ( undef ) is a strange but possible situation for very
348 # badly written code. It's not supported yet.
350 # TODO: Ugh, those sub refs look awful! Give them proper
354 'File::Copy::copy' => {
355 scalar => sub { not $_[0] },
356 list => sub { @_ == 1 and not $_[0] }
358 'File::Copy::move' => {
359 scalar => sub { not $_[0] },
360 list => sub { @_ == 1 and not $_[0] }
364 # Start by using Sub::Identify if it exists on this system.
366 eval { require Sub::Identify; Sub::Identify->import('get_code_info'); };
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.
377 *get_code_info = sub ($) {
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;
386 return ($cv->GV->STASH->NAME, $cv->GV->NAME);
392 return join( '::', get_code_info( $_[1] ) );
395 my %Hints_loaded = ();
398 my ($class, $sub) = @_;
400 my ($package) = ( $sub =~ /(.*)::/ );
402 if (not defined $package) {
405 "Internal error in autodie::hints::load_hints - no package found.
409 # Do nothing if we've already tried to load hints for
411 return if $Hints_loaded{$package}++;
413 my $hints_available = 0;
416 no strict 'refs'; ## no critic
418 if ($package->can('DOES') and $package->DOES(HINTS_PROVIDER) ) {
419 $hints_available = 1;
421 elsif ( ${"${package}::DOES"}{HINTS_PROVIDER.""} ) {
422 $hints_available = 1;
426 return if not $hints_available;
428 my %package_hints = %{ $package->AUTODIE_HINTS };
430 foreach my $sub (keys %package_hints) {
432 my $hint = $package_hints{$sub};
434 # Ensure we have a package name.
435 $sub = "${package}::$sub" if $sub !~ /::/;
437 # TODO - Currently we don't check for conflicts, should we?
438 $Hints{$sub} = $hint;
440 $class->normalise_hints(\%Hints, $sub);
447 sub normalise_hints {
448 my ($class, $hints, $sub) = @_;
450 if ( exists $hints->{$sub}->{fail} ) {
452 if ( exists $hints->{$sub}->{scalar} or
453 exists $hints->{$sub}->{list}
455 # TODO: Turn into a proper diagnostic.
457 local $Carp::CarpLevel = 1;
458 Carp::croak("fail hints cannot be provided with either scalar or list hints for $sub");
461 # Set our scalar and list hints.
463 $hints->{$sub}->{scalar} =
464 $hints->{$sub}->{list} = delete $hints->{$sub}->{fail};
470 # Check to make sure all our hints exist.
472 foreach my $hint (qw(scalar list)) {
473 if ( not exists $hints->{$sub}->{$hint} ) {
474 # TODO: Turn into a proper diagnostic.
476 local $Carp::CarpLevel = 1;
477 Carp::croak("$hint hint missing for $sub");
485 my ($class, $sub) = @_;
487 my $subname = $class->sub_fullname( $sub );
489 # If we have hints loaded for a sub, then return them.
491 if ( exists $Hints{ $subname } ) {
492 return $Hints{ $subname };
495 # If not, we try to load them...
497 $class->load_hints( $subname );
501 if ( exists $Hints{ $subname } ) {
502 return $Hints{ $subname };
505 # It's the caller's responsibility to use defaults if desired.
506 # This allows on autodie to insist on hints if needed.
513 my ($class, $sub, $hints) = @_;
516 $sub = $class->sub_fullname( $sub );
520 $sub or Carp::croak("Attempts to set_hints_for unidentifiable subroutine");
524 warn "autodie::hints: Setting $sub to hints: $hints\n";
527 $Hints{ $sub } = $hints;
529 $class->normalise_hints(\%Hints, $sub);
543 =item Attempts to set_hints_for unidentifiable subroutine
545 You've called C<< autodie::hints->set_hints_for() >> using a subroutine
546 reference, but that reference could not be resolved back to a
547 subroutine name. It may be an anonymous subroutine (which can't
548 be made autodying), or may lack a name for other reasons.
550 If you receive this error with a subroutine that has a real name,
551 then you may have found a bug in autodie. See L<autodie/BUGS>
552 for how to report this.
554 =item fail hints cannot be provided with either scalar or list hints for %s
556 When defining hints, you can either supply both C<list> and
557 C<scalar> keywords, I<or> you can provide a single C<fail> keyword.
558 You can't mix and match them.
560 =item %s hint missing for %s
562 You've provided either a C<scalar> hint without supplying
563 a C<list> hint, or vice-versa. You I<must> supply both C<scalar>
564 and C<list> hints, I<or> a single C<fail> hint.
568 =head1 ACKNOWLEDGEMENTS
574 Dr Damian Conway for suggesting the hinting interface and providing the
579 Jacinta Richardson for translating much of my ideas into this
586 Copyright 2009, Paul Fenwick E<lt>pjf@perltraining.com.auE<gt>
590 This module is free software. You may distribute it under the
591 same terms as Perl itself.
595 L<autodie>, L<Class::DOES>