I want to write a small subroutine that can decorate all error messages in a consistent way instead of having to copy it all around my program.
However I want the line numbers to be from where it was called, not from where the die
/warn
occurred.
In C I would just use a preprocessor macro, but Perl does not have those. What is the best way to implement this?
Use Carp for warnings/errors. You can use __WARN__
and __DIE__
hooks to affect what warn
prints to the STDERR
stream and how die
is thrown. Note that they are quite different.
use warnings;
use strict;
use feature 'say';
use Carp;
$SIG{__WARN__} = \&wrap_warn;
sub wrap_warn {
print "WARNING: @_";
}
sub level_2 {
say "Print from level_2";
carp "carp from level_2(@_)";
}
sub level_1 {
level_2(@_);
}
level_1("from main");
prints to STDOUT
Print from level_2
WARNING: carp from level_2(from main) at wrap_warn.pl line 19.
main::level_2('from main') called at wrap_warn.pl line 15
main::level_1('from main') called at wrap_warn.pl line 22
If you want this to still go to STDERR
then use print STDERR "WARNING: @_";
Make sure to carefully read about %SIG
in perlvar and warn, at least.
While it seems that you want this to be global, I'd like to mention that local-izing changes like this is generally what one wants, if possible. There's an example in this post, and more out there.
Adding the following will add stack traces to exceptions and warnings:
use Carp::Always;
For the occasional use, use the following to avoid modifying your program:
perl -MCarp::Always script args
or
PERL5OPT=-MCarp::Always script args