diff options
author | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2014-05-27 22:45:06 +0100 |
---|---|---|
committer | Chris 'BinGOs' Williams <chris@bingosnet.co.uk> | 2014-05-28 08:45:48 +0100 |
commit | f91d7e0d6f9534398b091503efca8c511bbf5174 (patch) | |
tree | 9f9cffa66e245fd8009cfe732015977b5d929d65 /cpan | |
parent | 153b7a01491d6e2a72f26ba722ea59d853189beb (diff) | |
download | perl-f91d7e0d6f9534398b091503efca8c511bbf5174.tar.gz |
Update autodie to CPAN version 2.25
[DELTA]
2.25 2014-04-03 09:43:15EST+1100 Australia/Melbourne
* DOCS: Spelling fixes in autodie::ScopeUtil
(Courtesy Salvatore Bonaccorso)
2.24 2014-03-30 19:30:10EST+1100 Australia/Melbourne
* FEATURE: Provide a stack backtrace when `Carp::Always` is enabled.
Note that sometimes this is not as pretty as it could
be, patches welcome.
(Thanks to Niels Thykier, GH #35)
* BUGFIX: Fix situations where `no autodie` doesn't respect lexical
scope. (Thanks to Niels Thykier, GH #41, RT #72053,
RT #86396)
* INTERNAL: Remove now unused variables in code (Niels Thykier).
* DOCS: Make it extra-clear autodie doesn't check `print`.
(Dave Rolsky, GH #39)
* TEST: Removed obsolete boilerplate.t
* TEST / INTERNAL: Enabled travis-ci for Perl 5.8
* TEST: Stopped some Pod::Coverage tests failing under Perl 5.8
* BUILD: Better support for building in a read-only directory
(courtesy Andrew Fresh, GH #46)
Diffstat (limited to 'cpan')
-rw-r--r-- | cpan/autodie/lib/Fatal.pm | 54 | ||||
-rw-r--r-- | cpan/autodie/lib/autodie.pm | 4 | ||||
-rw-r--r-- | cpan/autodie/lib/autodie/Scope/Guard.pm | 65 | ||||
-rw-r--r-- | cpan/autodie/lib/autodie/Scope/GuardStack.pm | 124 | ||||
-rw-r--r-- | cpan/autodie/lib/autodie/ScopeUtil.pm | 80 | ||||
-rw-r--r-- | cpan/autodie/lib/autodie/exception.pm | 31 | ||||
-rw-r--r-- | cpan/autodie/lib/autodie/exception/system.pm | 2 | ||||
-rw-r--r-- | cpan/autodie/lib/autodie/hints.pm | 4 | ||||
-rw-r--r-- | cpan/autodie/lib/autodie/skip.pm | 4 | ||||
-rw-r--r-- | cpan/autodie/t/scope_leak.t | 10 | ||||
-rw-r--r-- | cpan/autodie/t/truncate.t | 7 | ||||
-rw-r--r-- | cpan/autodie/t/truncate_me | 0 |
12 files changed, 338 insertions, 47 deletions
diff --git a/cpan/autodie/lib/Fatal.pm b/cpan/autodie/lib/Fatal.pm index e538e20d68..493219d850 100644 --- a/cpan/autodie/lib/Fatal.pm +++ b/cpan/autodie/lib/Fatal.pm @@ -10,6 +10,8 @@ use Tie::RefHash; # To cache subroutine refs use Config; use Scalar::Util qw(set_prototype); +use autodie::ScopeUtil qw(on_end_of_compile_scope); + use constant PERL510 => ( $] >= 5.010 ); use constant LEXICAL_TAG => q{:lexical}; @@ -48,7 +50,7 @@ use constant ERROR_58_HINTS => q{Non-subroutine %s hints for %s are not supporte use constant MIN_IPC_SYS_SIMPLE_VER => 0.12; -our $VERSION = '2.23'; # VERSION: Generated by DZP::OurPkg::Version +our $VERSION = '2.25'; # VERSION: Generated by DZP::OurPkg::Version our $Debug ||= 0; @@ -61,6 +63,10 @@ our %_EWOULDBLOCK = ( MSWin32 => 33, ); +$Carp::CarpInternal{'Fatal'} = 1; +$Carp::CarpInternal{'autodie'} = 1; +$Carp::CarpInternal{'autodie::exception'} = 1; + # the linux parisc port has separate EAGAIN and EWOULDBLOCK, # and the kernel returns EAGAIN my $try_EAGAIN = ($^O eq 'linux' and $Config{archname} =~ /hppa|parisc/) ? 1 : 0; @@ -145,6 +151,8 @@ my %TAGS = ( ':2.21' => [qw(:default)], ':2.22' => [qw(:default)], ':2.23' => [qw(:default)], + ':2.24' => [qw(:default)], + ':2.25' => [qw(:default)], ); # chmod was only introduced in 2.07 @@ -326,7 +334,6 @@ my %CORE_prototype_cache; # setting up lexical guards. my $PACKAGE = __PACKAGE__; -my $PACKAGE_GUARD = "guard $PACKAGE"; my $NO_PACKAGE = "no $PACKAGE"; # Used to detect 'no autodie' # Here's where all the magic happens when someone write 'use Fatal' @@ -467,9 +474,9 @@ sub import { # Our package guard gets invoked when we leave our lexical # scope. - push(@ { $^H{$PACKAGE_GUARD} }, autodie::Scope::Guard->new(sub { + on_end_of_compile_scope(sub { $class->_install_subs($pkg, \%unload_later); - })); + }); # To allow others to determine when autodie was in scope, # and with what arguments, we also set a %^H hint which @@ -561,7 +568,7 @@ sub unimport { # in which case, we disable Fatalistic behaviour for 'blah'. my @unimport_these = @_ ? @_ : ':all'; - my %uninstall_subs; + my (%uninstall_subs, %reinstall_subs); for my $symbol ($class->_translate_import_args(@unimport_these)) { @@ -580,6 +587,8 @@ sub unimport { # (eg, mixing Fatal with no autodie) $^H{$NO_PACKAGE}{$sub} = 1; + my $current_sub = \&$sub; + $reinstall_subs{$symbol} = $current_sub; if (my $original_sub = $Original_user_sub{$sub}) { # Hey, we've got an original one of these, put it back. @@ -595,6 +604,9 @@ sub unimport { } $class->_install_subs($pkg, \%uninstall_subs); + on_end_of_compile_scope(sub { + $class->_install_subs($pkg, \%reinstall_subs); + }); return; @@ -1197,7 +1209,7 @@ sub _one_invocation { sub _make_fatal { my($class, $sub, $pkg, $void, $lexical, $filename, $insist, $install_subs) = @_; - my($code, $sref, $real_proto, $proto, $core, $call, $hints, $cache, $cache_type); + my($code, $sref, $proto, $core, $call, $hints, $cache, $cache_type); my $ini = $sub; my $name = $sub; @@ -1434,14 +1446,8 @@ sub _make_fatal { my $installed_sub = $code; if ($lexical) { - my $real_proto = ''; - if (defined $proto) { - $real_proto = " ($proto)"; - } else { - $proto = '@'; - } $installed_sub = $class->_make_leak_guard($filename, $code, $sref, $call, - $pkg, $proto, $real_proto); + $pkg, $proto); } $cache->{$cache_type} = $code; @@ -1509,7 +1515,7 @@ sub exception_class { return "autodie::exception" }; # Creates and returns a leak guard (with prototype if needed). sub _make_leak_guard { - my ($class, $filename, $wrapped_sub, $orig_sub, $call, $pkg, $proto, $real_proto) = @_; + my ($class, $filename, $wrapped_sub, $orig_sub, $call, $pkg, $proto) = @_; # The leak guard is rather lengthly (in fact it makes up the most # of _make_leak_guard). It is possible to split it into a large @@ -1632,7 +1638,7 @@ sub _make_leak_guard { # If there is a prototype on the original sub, copy it to the leak # guard. - if ($real_proto ne '') { + if (defined $proto) { # The "\&" may appear to be redundant but set_prototype # croaks when it is removed. set_prototype(\&$leak_guard, $proto); @@ -1758,24 +1764,6 @@ sub _autocroak { exit(255); # Ugh! } -package autodie::Scope::Guard; - -# This code schedules the cleanup of subroutines at the end of -# scope. It's directly inspired by chocolateboy's excellent -# Scope::Guard module. - -sub new { - my ($class, $handler) = @_; - - return bless $handler, $class; -} - -sub DESTROY { - my ($self) = @_; - - $self->(); -} - 1; __END__ diff --git a/cpan/autodie/lib/autodie.pm b/cpan/autodie/lib/autodie.pm index ed5a612efe..f2c98c2367 100644 --- a/cpan/autodie/lib/autodie.pm +++ b/cpan/autodie/lib/autodie.pm @@ -10,7 +10,7 @@ our $VERSION; # ABSTRACT: Replace functions with ones that succeed or die with lexical scope BEGIN { - our $VERSION = '2.23'; # VERSION: Generated by DZP::OurPkg::Version + our $VERSION = '2.25'; # VERSION: Generated by DZP::OurPkg::Version } use constant ERROR_WRONG_FATAL => q{ @@ -88,6 +88,8 @@ autodie - Replace functions with ones that succeed or die with lexical scope open(my $fh, "<", $filename); # Could fail silently! no autodie; # disable all autodies } + + print "Hello World" or die $!; # autodie DOESN'T check print! =head1 DESCRIPTION diff --git a/cpan/autodie/lib/autodie/Scope/Guard.pm b/cpan/autodie/lib/autodie/Scope/Guard.pm new file mode 100644 index 0000000000..053399a134 --- /dev/null +++ b/cpan/autodie/lib/autodie/Scope/Guard.pm @@ -0,0 +1,65 @@ +package autodie::Scope::Guard; + +use strict; +use warnings; + +# ABSTRACT: Wrapper class for calling subs at end of scope +our $VERSION = '2.25'; # VERSION + +# This code schedules the cleanup of subroutines at the end of +# scope. It's directly inspired by chocolateboy's excellent +# Scope::Guard module. + +sub new { + my ($class, $handler) = @_; + return bless($handler, $class); +} + +sub DESTROY { + my ($self) = @_; + + $self->(); +} + +1; + +__END__ + +=head1 NAME + +autodie::Scope::Guard - Wrapper class for calling subs at end of scope + +=head1 SYNOPSIS + + use autodie::Scope::Guard; + $^H{'my-key'} = autodie::Scope::Guard->new(sub { + print "Hallo world\n"; + }); + +=head1 DESCRIPTION + +This class is used to bless perl subs so that they are invoked when +they are destroyed. This is mostly useful for ensuring the code is +invoked at end of scope. This module is not a part of autodie's +public API. + +This module is directly inspired by chocolateboy's excellent +Scope::Guard module. + +=head2 Methods + +=head3 new + + my $hook = autodie::Scope::Guard->new(sub {}); + +Creates a new C<autodie::Scope::Guard>, which will invoke the given +sub once it goes out of scope (i.e. its DESTROY handler is called). + +=head1 AUTHOR + +Copyright 2008-2009, Paul Fenwick E<lt>pjf@perltraining.com.auE<gt> + +=head1 LICENSE + +This module is free software. You may distribute it under the +same terms as Perl itself. diff --git a/cpan/autodie/lib/autodie/Scope/GuardStack.pm b/cpan/autodie/lib/autodie/Scope/GuardStack.pm new file mode 100644 index 0000000000..844dcf4d6b --- /dev/null +++ b/cpan/autodie/lib/autodie/Scope/GuardStack.pm @@ -0,0 +1,124 @@ +package autodie::Scope::GuardStack; + +use strict; +use warnings; + +use autodie::Scope::Guard; + +# ABSTRACT: Hook stack for managing scopes via %^H +our $VERSION = '2.25'; # VERSION + +my $H_KEY_STEM = __PACKAGE__ . '/guard'; +my $COUNTER = 0; + +# This code schedules the cleanup of subroutines at the end of +# scope. It's directly inspired by chocolateboy's excellent +# Scope::Guard module. + +sub new { + my ($class) = @_; + + return bless([], $class); +} + +sub push_hook { + my ($self, $hook) = @_; + my $h_key = $H_KEY_STEM . ($COUNTER++); + my $size = @{$self}; + $^H{$h_key} = autodie::Scope::Guard->new(sub { + # Pop the stack until we reach the right size + # - this may seem weird, but it is to avoid relying + # on "destruction order" of keys in %^H. + # + # Example: + # { + # use autodie; # hook 1 + # no autodie; # hook 2 + # use autodie; # hook 3 + # } + # + # Here we want call hook 3, then hook 2 and finally hook 1. + # Any other order could have undesired consequences. + # + # Suppose hook 2 is destroyed first, it will pop hook 3 and + # then hook 2. hook 3 will then be destroyed, but do nothing + # since its "frame" was already popped and finally hook 1 + # will be popped and take its own frame with it. + $self->_pop_hook while @{$self} > $size; + }); + push(@{$self}, [$hook, $h_key]); + return; +} + +sub _pop_hook { + my ($self) = @_; + my ($hook, $key) = @{ pop(@{$self}) }; + my $ref = delete($^H{$key}); + $hook->(); + return; +} + +sub DESTROY { + my ($self) = @_; + + # To be honest, I suspect @{$self} will always be empty here due + # to the subs in %^H having references to the stack (which would + # keep the stack alive until those have been destroyed). Anyhow, + # it never hurt to be careful. + $self->_pop_hook while @{$self}; + return; +} + +1; + +__END__ + +=head1 NAME + +autodie::Scope::GuardStack - Hook stack for managing scopes via %^H + +=head1 SYNOPSIS + + use autodie::Scope::GuardStack; + my $stack = autodie::Scope::GuardStack->new + $^H{'my-key'} = $stack; + + $stack->push_hook(sub {}); + +=head1 DESCRIPTION + +This class is a stack of hooks to be called in the right order as +scopes go away. The stack is only useful when inserted into C<%^H> +and will pop hooks as their "scope" is popped. This is useful for +uninstalling or reinstalling subs in a namespace as a pragma goes +out of scope. + +Due to how C<%^H> works, this class is only useful during the +compilation phase of a perl module and relies on the internals of how +perl handles references in C<%^H>. This module is not a part of +autodie's public API. + +=head2 Methods + +=head3 new + + my $stack = autodie::Scope::GuardStack->new; + +Creates a new C<autodie::Scope::GuardStack>. The stack is initially +empty and must be inserted into C<%^H> by the creator. + +=head3 push_hook + + $stack->push_hook(sub {}); + +Add a sub to the stack. The sub will be called once the current +compile-time "scope" is left. Multiple hooks can be added per scope + +=head1 AUTHOR + +Copyright 2013, Niels Thykier E<lt>niels@thykier.netE<gt> + +=head1 LICENSE + +This module is free software. You may distribute it under the +same terms as Perl itself. diff --git a/cpan/autodie/lib/autodie/ScopeUtil.pm b/cpan/autodie/lib/autodie/ScopeUtil.pm new file mode 100644 index 0000000000..bf7f8363a1 --- /dev/null +++ b/cpan/autodie/lib/autodie/ScopeUtil.pm @@ -0,0 +1,80 @@ +package autodie::ScopeUtil; + +use strict; +use warnings; + +# Docs say that perl 5.8.3 has Exporter 5.57 and autodie requires +# 5.8.4, so this should "just work". +use Exporter 5.57 qw(import); + +use autodie::Scope::GuardStack; + +our @EXPORT_OK = qw(on_end_of_compile_scope); + +# ABSTRACT: Utilities for managing %^H scopes +our $VERSION = '2.25'; # VERSION + +# docs says we should pick __PACKAGE__ /<whatever> +my $H_STACK_KEY = __PACKAGE__ . '/stack'; + +sub on_end_of_compile_scope { + my ($hook) = @_; + + # Dark magic to have autodie work under 5.8 + # Copied from namespace::clean, that copied it from + # autobox, that found it on an ancient scroll written + # in blood. + + # This magic bit causes %^H to be lexically scoped. + $^H |= 0x020000; + + my $stack = $^H{$H_STACK_KEY}; + if (not defined($stack)) { + $stack = autodie::Scope::GuardStack->new; + $^H{$H_STACK_KEY} = $stack; + } + + $stack->push_hook($hook); + return; +} + +1; + +=head1 NAME + +autodie::ScopeUtil - Utilities for managing %^H scopes + +=head1 SYNOPSIS + + use autodie::ScopeUtil qw(on_end_of_compile_scope); + on_end_of_compile_scope(sub { print "Hallo world\n"; }); + +=head1 DESCRIPTION + +Utilities for abstracting away the underlying magic of (ab)using +C<%^H> to call subs at the end of a (compile-time) scopes. + +Due to how C<%^H> works, these utilities are only useful during the +compilation phase of a perl module and relies on the internals of how +perl handles references in C<%^H>. This module is not a part of +autodie's public API. + +=head2 Methods + +=head3 on_end_of_compile_scope + + on_end_of_compile_scope(sub { print "Hallo world\n"; }); + +Will invoke a sub at the end of a (compile-time) scope. The sub is +called once with no arguments. Can be called multiple times (even in +the same "compile-time" scope) to install multiple subs. Subs are +called in a "first-in-last-out"-order (FILO or "stack"-order). + +=head1 AUTHOR + +Copyright 2013, Niels Thykier E<lt>niels@thykier.netE<gt> + +=head1 LICENSE + +This module is free software. You may distribute it under the +same terms as Perl itself. diff --git a/cpan/autodie/lib/autodie/exception.pm b/cpan/autodie/lib/autodie/exception.pm index 0081860576..3709d58f16 100644 --- a/cpan/autodie/lib/autodie/exception.pm +++ b/cpan/autodie/lib/autodie/exception.pm @@ -4,7 +4,7 @@ use strict; use warnings; use Carp qw(croak); -our $VERSION = '2.23'; # VERSION: Generated by DZP::OurPkg:Version +our $VERSION = '2.25'; # VERSION: Generated by DZP::OurPkg:Version # ABSTRACT: Exceptions from autodying functions. our $DEBUG = 0; @@ -540,6 +540,7 @@ sub stringify { my ($this) = @_; my $call = $this->function; + my $msg; if ($DEBUG) { my $dying_pkg = $this->package; @@ -550,11 +551,14 @@ sub stringify { # TODO - This isn't using inheritance. Should it? if ( my $sub = $formatter_of{$call} ) { - return $sub->($this) . $this->add_file_and_line; + $msg = $sub->($this) . $this->add_file_and_line; + } else { + $msg = $this->format_default . $this->add_file_and_line; } + $msg .= $this->{$PACKAGE}{_stack_trace} + if $Carp::Verbose; - return $this->format_default . $this->add_file_and_line; - + return $msg; } =head3 format_default @@ -722,7 +726,24 @@ sub _init { $this->{$PACKAGE}{file} = $file; $this->{$PACKAGE}{line} = $line; $this->{$PACKAGE}{caller} = $sub; - $this->{$PACKAGE}{package} = $package; + + # Tranks to %Carp::CarpInternal all Fatal, autodie and + # autodie::exception stack frames are filtered already, but our + # nameless wrapper is still present, so strip that. + + my $trace = Carp::longmess(); + $trace =~ s/^\s*at \(eval[^\n]+\n//; + + # And if we see an __ANON__, then we'll replace that with the actual + # name of our autodying function. + + my $short_func = $args{function}; + $short_func =~ s/^CORE:://; + $trace =~ s/(\s*[\w:]+)__ANON__/$1$short_func/; + + # And now we just fill in all our attributes. + + $this->{$PACKAGE}{_stack_trace} = $trace; $this->{$PACKAGE}{errno} = $args{errno} || 0; diff --git a/cpan/autodie/lib/autodie/exception/system.pm b/cpan/autodie/lib/autodie/exception/system.pm index 2d734fe7f2..08e6c5bb35 100644 --- a/cpan/autodie/lib/autodie/exception/system.pm +++ b/cpan/autodie/lib/autodie/exception/system.pm @@ -5,7 +5,7 @@ use warnings; use base 'autodie::exception'; use Carp qw(croak); -our $VERSION = '2.23'; # VERSION: Generated by DZP::OurPkg:Version +our $VERSION = '2.25'; # VERSION: Generated by DZP::OurPkg:Version # ABSTRACT: Exceptions from autodying system(). diff --git a/cpan/autodie/lib/autodie/hints.pm b/cpan/autodie/lib/autodie/hints.pm index 17c898a900..b58d09b16c 100644 --- a/cpan/autodie/lib/autodie/hints.pm +++ b/cpan/autodie/lib/autodie/hints.pm @@ -5,7 +5,7 @@ use warnings; use constant PERL58 => ( $] < 5.009 ); -our $VERSION = '2.23'; # VERSION: Generated by DZP::OurPkg:Version +our $VERSION = '2.25'; # VERSION: Generated by DZP::OurPkg:Version # ABSTRACT: Provide hints about user subroutines to autodie @@ -597,6 +597,6 @@ same terms as Perl itself. L<autodie>, L<Class::DOES> -=for Pod::Coverage get_hints_for load_hints normalise_hints sub_fullname +=for Pod::Coverage get_hints_for load_hints normalise_hints sub_fullname get_code_info =cut diff --git a/cpan/autodie/lib/autodie/skip.pm b/cpan/autodie/lib/autodie/skip.pm index af40662810..c4531b5467 100644 --- a/cpan/autodie/lib/autodie/skip.pm +++ b/cpan/autodie/lib/autodie/skip.pm @@ -2,7 +2,7 @@ package autodie::skip; use strict; use warnings; -our $VERSION = '2.23'; # VERSION +our $VERSION = '2.25'; # VERSION # This package exists purely so people can inherit from it, # which isn't at all how roles are supposed to work, but it's @@ -51,4 +51,6 @@ terms as Perl itself. L<autodie>, L<autodie::exception> +=for Pod::Coverage DOES + =cut diff --git a/cpan/autodie/t/scope_leak.t b/cpan/autodie/t/scope_leak.t index c97b82f2df..047335d6b6 100644 --- a/cpan/autodie/t/scope_leak.t +++ b/cpan/autodie/t/scope_leak.t @@ -85,3 +85,13 @@ eval q{ ok($@,"Wacky flipping of autodie in string eval should work too!"); isa_ok($@, 'autodie::exception'); + +eval q{ + # RT#72053 + use autodie; + { no autodie; } + open(my $fh, '<', NO_SUCH_FILE); +}; + +ok($@,"Wacky flipping of autodie in string eval should work too!"); +isa_ok($@, 'autodie::exception'); diff --git a/cpan/autodie/t/truncate.t b/cpan/autodie/t/truncate.t index 2472139a1a..df6270e6f4 100644 --- a/cpan/autodie/t/truncate.t +++ b/cpan/autodie/t/truncate.t @@ -6,13 +6,12 @@ use File::Temp qw(tempfile); use IO::Handle; use File::Spec; use FindBin qw($Bin); -use constant TRUNCATE_ME => File::Spec->catfile($Bin,'truncate_me'); -my ($truncate_status, $tmpfh); +my ($truncate_status, $tmpfh, $tmpfile); # Some systems have a screwy tempfile. We don't run our tests there. eval { - $tmpfh = tempfile(); + ($tmpfh, $tmpfile) = tempfile(); }; if ($@ or !defined $tmpfh) { @@ -80,7 +79,7 @@ isa_ok($@, 'autodie::exception', "Truncating unopened file (TRUNCATE_FH)"); # wrong with our tests, or autodie... { use autodie qw(open); - open(TRUNCATE_FH, '+<', TRUNCATE_ME); + open(TRUNCATE_FH, '+<', $tmpfile); } # Now try truncating the filehandle. This should succeed. diff --git a/cpan/autodie/t/truncate_me b/cpan/autodie/t/truncate_me deleted file mode 100644 index e69de29bb2..0000000000 --- a/cpan/autodie/t/truncate_me +++ /dev/null |