Use of uninitialized value in string — promoting warning to fatal error across Perl versions
0 reputation · 21 Dec 2020, 08:03 UTC
0 reputation · 21 Dec 2020, 08:03 UTC
The warning "Use of uninitialized value $var in string" fires whenever an undefined scalar is interpolated or concatenated. The core warnings pragma reports it but lacks a built-in mechanism to treat this specific category as fatal.
Community discussions reference use warnings FATAL => 'uninitialized'; yet this syntax does not appear in the official perlwarning documentation. Perl 5.36 and 5.38 show internal handling changes that may affect whether the promotion behaves consistently.
Elevating the warning breaks legacy code that depends on implicit undef-to-empty-string conversion, and there is no documented way to silence only uninitialized warnings while keeping other categories active.
use warnings FATAL => 'uninitialized'; guaranteed to work across current and future Perl releases?35275 reputation · 21 Dec 2020, 17:48 UTC
1. Is use warnings FATAL => 'uninitialized'; guaranteed across current and future Perl releases? No. The FATAL option is present in current Perl and works today, but there is no formal stability guarantee for the exact syntax and implementation across future releases. Core warnings internals were refactored around Perl 5.36/5.38, so behavior can be version sensitive even when the feature is present.
2. Supported method to promote only the uninitialized category to fatal. The supported method is the warnings pragma with a lexical FATAL list:
{ use warnings FATAL => 'uninitialized';
my $v;
"value=$v";
}
This makes any warning from the uninitialized category die inside the dynamic scope. It does not affect other warning categories. FATAL applies to the whole uninitialized category, not only "in string" messages.
3. Lexical scope without altering global behavior? Yes. use warnings is lexical. A use warnings FATAL => 'uninitialized' inside a block or subroutine is active only for that dynamic scope and does not change warnings outside it.
use warnings FATAL => 'uninitialized' makes uninitialized warnings die in the scope where it is in effect, and does not change warnings outside that scope.sub safe_interpolate {
use warnings FATAL => 'uninitialized';
my $v = shift;
return "value=$v";
}
perl -v
Create a minimal script with an undef interpolated inside a FATAL block and confirm it dies, and outside the block it only warns.
no warnings can be surprising.One diagnostic detail that changes the recommendation: do you need only "Use of uninitialized value in string" to be fatal, or the entire uninitialized category? FATAL cannot filter sub-messages; if you need only string interpolation, a $SIG{__WARN__} filter is required.
Use comments to ask for clarification. Post a solution as an answer.
35,275 reputation · 21 Dec 2020, 10:00 UTC
The warning category documentation lives in perllexwarn and the warnings pragma perldoc — perlwarning does not exist. The FATAL keyword must be uppercase; fatal (lowercase) is silently ignored and will not promote the category. Also, any third-party code that executes no warnings; (without a category list) inside its own scope will suppress the fatal behavior there, which can mask the very errors you're trying to catch. If you control the call chain, wrap the risky interpolation in a minimal block with use warnings FATAL => 'uninitialized'; and verify with perl -Mwarnings=FATAL,uninitialized -e 'print $undef' on your target Perl (5.36+).