How can I suppress warnings from a Perl function?
Solution 1
This feature of PHP is crazy and should be avoided whenever possible.
Perl has two kinds of exceptions: Fatal errors and warnings. Warnings may either be emitted by Perl itself, or by user code.
Inside a certain static/lexical scope, Perl's builtin warnings can be switched off like:
use warnings;
foo();
sub foo {
no warnings 'uninitialized'; # recommended: only switch of specific categories
warn "hello\n";
1 + undef; # Otherwise: Use of uninitialized value in addition (+)
}
Output: hello
on STDERR.
(A list of all warnings categories can be found here )
But this can't be used to remove warnings from code you are calling (dynamic scope). This also doesn't silence user-defined warnings.
In this case, you can write a handler for the __WARN__
pseudo-signal:
use warnings;
{
local $SIG{__WARN__} = sub { };
foo();
print "bye\n";
}
sub foo {
warn "hello\n";
1 + undef;
}
Output: bye
on STDOUT.
We can abstract that into a function muffle
:
sub muffle {
my $func = shift;
local $SIG{__WARN__} = sub { };
return $func->(@_);
}
muffle(\&foo, 1, 2, 3); # foo(1, 2, 3)
However, this is an incredibly dumb thing to do:
- Warnings point to potential problems and bugs. Fix those instead of ignoring them.
- Don't activate built-in warnings in the first place for categories you aren't interested in. E.g. many people are perfectly happy that an
undef
value stringifies to the empty string, and don't want any warning for that.
The strategies outlined here do not handle fatal exceptions, use Try::Tiny
instead.
Solution 2
You could also just run perl -X
and disable all warnings.
I think there are perfectly valid reasons for doing this FWIW.
andrius.k
Updated on July 10, 2020Comments
-
andrius.k almost 4 years
In PHP you might use
@
in front of function call to suppress warnings returned.Is there something similar in Perl?
-
mpapec over 10 yearsbtw, what is a reason why warnings can't be silenced by localising STDERR?
perl -e 'local *STDERR; warn 4'
-
amon over 10 years@mpapec Interesting … I'd wager the guess that
warn
and builtin warnings do not look up the*main::STDERR
symbol when executed, and they just print to the file handle directly. But re-opening the file handle works fine… Maybe somebody knows the answer when you post this as a proper question here. I'm curious. -
mpapec over 10 yearstnx amon, I've posted separate question
-
OrangeDog almost 8 yearsMaybe emphasise more that it's an incredibly dumb thing to do.
-
Medlock Perlman over 6 yearsQuite right, such as when you're working on production code that emits unnecessary or not-very-useful warnings that haven't been cleaned up yet. Or to test whether you've written something somewhere that is creating a ton of warnings.