summaryrefslogtreecommitdiff
path: root/dist/Carp
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2018-03-11 15:28:27 -0700
committerFather Chrysostomos <sprout@cpan.org>2018-03-11 17:23:34 -0700
commit5d70f8f9a94124c9e77138d92611f5765f8793ad (patch)
tree670c6992ad53225a363e347a9871ef69aa5f6e07 /dist/Carp
parentf8b8ba603b2ee25a74c91b3f9e292db14b2f4ab6 (diff)
downloadperl-5d70f8f9a94124c9e77138d92611f5765f8793ad.tar.gz
Carp: Use ${^LAST_FH} if available
Using ${^LAST_FH}, available in 5.18, in faster than using eval/die to get the last file handle. Also, the eval/die method is not going to produce anything if $. is 0 so skip that entire block if $. is false (by removing the defined check). (Not significant enough for perldelta. carp("zonk") gets faster by only 5% or so.)
Diffstat (limited to 'dist/Carp')
-rw-r--r--dist/Carp/lib/Carp.pm21
1 files changed, 20 insertions, 1 deletions
diff --git a/dist/Carp/lib/Carp.pm b/dist/Carp/lib/Carp.pm
index 25ba942ad1..97f6604a17 100644
--- a/dist/Carp/lib/Carp.pm
+++ b/dist/Carp/lib/Carp.pm
@@ -571,6 +571,15 @@ sub longmess_heavy {
return ret_backtrace( $i, @_ );
}
+BEGIN {
+ if("$]" >= 5.017004) {
+ # The LAST_FH constant is a reference to the variable.
+ $Carp::{LAST_FH} = \eval '\${^LAST_FH}';
+ } else {
+ eval '*LAST_FH = sub () { 0 }';
+ }
+}
+
# Returns a full stack backtrace starting from where it is
# told.
sub ret_backtrace {
@@ -587,7 +596,16 @@ sub ret_backtrace {
my %i = caller_info($i);
$mess = "$err at $i{file} line $i{line}$tid_msg";
- if( defined $. ) {
+ if( $. ) {
+ # Use ${^LAST_FH} if available.
+ if (LAST_FH) {
+ if (${+LAST_FH}) {
+ $mess .= sprintf ", <%s> %s %d",
+ *${+LAST_FH}{NAME},
+ ($/ eq "\n" ? "line" : "chunk"), $.
+ }
+ }
+ else {
local $@ = '';
local $SIG{__DIE__};
eval {
@@ -596,6 +614,7 @@ sub ret_backtrace {
if($@ =~ /^Died at .*(, <.*?> (?:line|chunk) \d+).$/ ) {
$mess .= $1;
}
+ }
}
$mess .= "\.\n";