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