http://qs321.pair.com?node_id=1220276

Carp::Always is a minimalist debugging aid, often used from the command line with usage patterns like
perl -MCarp::Always script.pl
or
PERL5OPT=-MCarp::Always script.pl
Using Carp::Always decorates the output of each warn() and die() with stacktraces. For example,
$ perl -MCarp::Always -e 'sub f { die "arghh" }; sub g { f }; g;' arghh at -e line 1 main::f() called at -e line 1 main::g() called at -e line 1

This is meant to help finding where issues actually coming from at the code being inspected.

Last week I had the chance to revisit Carp::Always code. It was basically abandoned since the 0.13 release back in 2013. One could say that there was not much work to do about it and that it withstood the test of times as many other CPAN modules that haven't seen updates in a long time. That is not quite true: the bug backlog kept growing and it is quite possible that the few Carp::Always users may have disbanded to newer alternatives like Devel::Confess.

The main changes in the latest 0.16 release are:

  • Fix for a long standing bug with duplicate tracebacks - see a mention of it in the 2011 Perl Advent
  • Carp::Always now enabled / disabled by import() / unimport() rather than using BEGIN and END blocks

The bug backlog has been cleared (both at GitHub and CPAN RT queue) to make room for brand new bugs. =)

Hopefully, these updates will extend Carp::Always lifetime and usefulness. You're invited to give it a try.

Replies are listed 'Best First'.
Re: Carp::Always comeback [tests with autodie]
by kcott (Archbishop) on Aug 13, 2018 at 10:10 UTC

    G'day ferreira,

    ++ Thanks for the module update and notification.

    "You're invited to give it a try."

    I've never used this module previously. It installed without any problems, by the way. I noted in Carp::Always - BUGS the issue that it "... does not play well with other modules which fusses around with warn, die, ...". I have an alias which I use often for testing code snippets; it uses autodie; I wondered if there would be any issues using the two together.

    Here's the playing field:

    $ uname -a Darwin ganymede.local 16.6.0 Darwin Kernel Version 16.6.0: Fri Apr 14 +16:21:16 PDT 2017; root:xnu-3789.60.24~6/RELEASE_X86_64 x86_64 i386 M +acPro5,1 Darwin $ perl -v | head -2 | tail -1 This is perl 5, version 28, subversion 0 (v5.28.0) built for darwin-th +read-multi-2level $ alias perle alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -E' $ ls not_a_file ls: cannot access 'not_a_file': No such file or directory

    I tried a number of tests (mostly based on the code example in your OP) using '-M' and 'use', with different load orders.

    $ perle 'use Carp::Always; die "arghh"' arghh at -e line 1. $ perle 'use Carp::Always; sub f { die "arghh" }; sub g { f }; g;' arghh at -e line 1. main::f() called at -e line 1 main::g() called at -e line 1 $ perle 'use Carp::Always; sub f { open my $fh, "<", "not_a_file" }; s +ub g { f }; g;' Can't open 'not_a_file' for reading: 'No such file or directory' at -e + line 1 main::open(GLOB(0x7feaba80e750), "<", "not_a_file") called at -e l +ine 1 main::f() called at -e line 1 main::g() called at -e line 1 $ perl -Mstrict -Mwarnings -MCarp::Always -Mautodie=:all -E 'sub f { o +pen my $fh, "<", "not_a_file" }; sub g { f }; g;' Can't open 'not_a_file' for reading: 'No such file or directory' at -e + line 1 main::open(GLOB(0x7ff52b80d950), "<", "not_a_file") called at -e l +ine 1 main::f() called at -e line 1 main::g() called at -e line 1 $ perl -Mstrict -Mwarnings -Mautodie=:all -MCarp::Always -E 'sub f { o +pen my $fh, "<", "not_a_file" }; sub g { f }; g;' Can't open 'not_a_file' for reading: 'No such file or directory' at -e + line 1 main::open(GLOB(0x7f955100d950), "<", "not_a_file") called at -e l +ine 1 main::f() called at -e line 1 main::g() called at -e line 1 $ perl -Mstrict -Mwarnings -E 'use autodie ":all"; use Carp::Always; s +ub f { open my $fh, "<", "not_a_file" }; sub g { f }; g;' Can't open 'not_a_file' for reading: 'No such file or directory' at -e + line 1 main::open(GLOB(0x7f7f6480d950), "<", "not_a_file") called at -e l +ine 1 main::f() called at -e line 1 main::g() called at -e line 1 $ perl -Mstrict -Mwarnings -E 'use Carp::Always; use autodie ":all"; s +ub f { open my $fh, "<", "not_a_file" }; sub g { f }; g;' Can't open 'not_a_file' for reading: 'No such file or directory' at -e + line 1 main::open(GLOB(0x7fb6fa032b50), "<", "not_a_file") called at -e l +ine 1 main::f() called at -e line 1 main::g() called at -e line 1 $ perl -Mstrict -Mwarnings -E 'use autodie ":all"; sub f { open my $fh +, "<", "not_a_file" }; sub g { f }; g;' Can't open 'not_a_file' for reading: 'No such file or directory' at -e + line 1 $ perl -Mstrict -Mwarnings -E 'use Carp::Always; sub f { open my $fh, +"<", "not_a_file" }; sub g { f }; g;' $ perl -Mstrict -Mwarnings -E 'sub f { open my $fh, "<", "not_a_file" +}; sub g { f }; g;' $ perl -E 'sub f { open my $fh, "<", "not_a_file" }; sub g { f }; g;' $

    While that in no way tests the full fucntionality of autodie against Carp::Always; it was sufficient for me to update my alias:

    $ alias perle alias perle='perl -Mstrict -Mwarnings -Mautodie=:all -MCarp::Always -E +'

    And that now works as expected:

    $ perle 'sub f { open my $fh, "<", "not_a_file" }; sub g { f }; g;' Can't open 'not_a_file' for reading: 'No such file or directory' at -e + line 1 main::open(GLOB(0x7fb28e80f750), "<", "not_a_file") called at -e l +ine 1 main::f() called at -e line 1 main::g() called at -e line 1

    So, thanks again and, if I do encounter any problems in the future, I'll let you know.

    — Ken