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