I want to have fatal errors that can be demoted to warnings (or conversely, warnings that can be promoted to fatal errors) depending on the user's preference. At present, I'm using die
and overriding it like this:
my $force;
BEGIN {
no warnings 'once';
Getopt::Long::Configure('pass_through');
GetOptions('force', \$force);
*CORE::GLOBAL::die = sub { warn @_ } if $force;
Getopt::Long::Configure('no_pass_through');
}
use My::Module;
...
die "maybe";
...
exit(1) if $force;
exit(0); # success!
I don't like this approach, mostly because there are a few places where I still want to die (e.g. missing command-line arguments). I'd rather change (most) instances of die
to warn
and do a conditional use warnings FATAL => 'all'
1. The problem is that use warnings
is lexically scoped, so this is ineffective:
if (!$force) {
use warnings FATAL => 'all';
}
Attempting to use a postfix conditional is a syntax error:
use warnings FATAL => 'all' unless $force;
and use
can't be used in an expression:
$force or use warnings FATAL => 'all'; # syntax error
I can think of various distasteful work-arounds (Defining my own warn/die, duplicating my main script code in an if/else, etc.) but am seeking an elegant solution that conditionally applies use warnings
in the current lexical scope. (Applying it in the parent scope would work as well but would likely require dark magic.)
use warnings::register
to my modules and use warnings FATAL => 'My::Module'
to my script, but the distinction is unimportant for the purposes of this question.
You could try:
use if !$force, warnings => qw( FATAL all );
Yes, there's a module called if
that is distributed with Perl to make it really easy to do conditional imports.
Note that this is evaluated at compile time, so $force
needs to be defined at compile time. (Probably within a BEGIN { ... }
block.) Based on the code samples in your question, you seem to have figured that part out already though.
Alternatively, more manual:
BEGIN {
require warnings;
warnings->import(qw/ FATAL all /) unless $force;
}
A completely different approach would be to use a signal handler $SIG{__WARN__}
or $SIG{__DIE__}
to decide to die or not at run-time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With