Beefy Boxes and Bandwidth Generously Provided by pair Networks kudra
Think about Loose Coupling
 
PerlMonks  

diagnostics masks "uninitialized value in range (or flip)" warning

by toolic (Chancellor)
on Dec 08, 2009 at 15:37 UTC ( #811761=perlmeditation: print w/ replies, xml ) Need Help??

Issue

use diagnostics masks the following type of warning when use warnings is in effect:
Use of uninitialized value in range (or flip)

Evidence

Here, we get the warning message, as desired:
$ perl -w -e 'my $x = 1..3' Use of uninitialized value in range (or flip) at -e line 1. $
Now, add diagnostics so we can get a more verbose explanation of the warning message:
$ perl -w -e 'my $x = 1..3' -Mdiagnostics $
D'oh! Not only did diagnostics not display additional information, but it also made the warning message disappear. WTF?

Furthermore, if diagnostics is used in conjunction with

use warnings FATAL => 'all';
the script will not die because of the warning.

Workaround

We can't use diagnostics to get more information on this warning, but we can still use splain to do the job:
$ echo 'Use of uninitialized value in range (or flip)' | splain Use of uninitialized value in range (or flip) (#1) (W uninitialized) An undefined value was used as if it were alread +y defined. It was interpreted as a "" or a 0, but maybe it was a mi +stake. To suppress this warning assign a defined value to your variables. To help you figure out what was undefined, perl tells you what ope +ration you used the undefined value in. Note, however, that perl optimiz +es your program and the operation displayed in the warning may not necessa +rily appear literally in your program. For example, "that $foo" is usually optimized into "that " . $foo, and the warning will refer +to the concatenation (.) operator, even though there is no . in your program.
Well, this message is not all that helpful because it does not seem specific to this case. That's a separate issue for perldiag, which can be dealt with on another day.

Root cause

Here is my hypothesis on why this happens. A quote from Range Operator:
If either operand of scalar ".." is a constant expression, that operand is considered true if it is equal ("==") to the current input line number (the $. variable).
By default, $. is undefined:
$ perl -w -e 'print ">>>$.<<<\n"' Use of uninitialized value in concatenation (.) or string at -e line 1 +. >>><<< $
Unless you use diagnostics:
$ perl -w -e 'print ">>>$.<<<\n"' -Mdiagnostics >>>0<<< $
So, it seems that diagnostics has the side effect of initializing the $. variable. I see some calls to open in the source code. Perhaps diagnostics is opening a file handle which is giving the global $. variable a value, thereby suppressing the warning message.

Possible solution

If I modify diagnostics.pm by adding the following line to localize $., the problem is fixed:
local $.;

What next

This is a bug. Unless the monks can convince me otherwise, I plan to submit this patch as a bug report via perlbug:
--- diagnostics.pm 2009-06-15 04:21:42.000000000 -0400 +++ diagnostics.pm.fix 2009-12-05 10:29:53.096561000 -0500 @@ -222,6 +222,7 @@ local $| = 1; my $_; +local $.; my $standalone; my(%HTML_2_Troff, %HTML_2_Latin_1, %HTML_2_ASCII_7);

Recommended usage

Until this gets fixed, make sure you use diagnostics only when you need it. Do not keep use diagnostics; in your code indefinitely. Unfortunately, I have done this in many of my scripts, and I must now go back and comment them out.

This is similar to tye's advice in (tye)Re: use diagnostics eats memory?.

Version

$ perl -v This is perl, v5.10.0 built for x86_64-linux
The $VERSION of diagnostics.pm is 1.17. The latest version I can find on CPAN is 1.18, and the issue exists there too.

Acknowledgments

In trying to unravel a range operator mystery, a Super Search led me to an observation by QM. I could not see the warning message because I had use diagnostics; in my code.

Update: Dec. 11, 2009: submitted bug report: http://rt.perl.org/rt3/Public/Bug/Display.html?id=71204
Update: Apr. 13, 2010: confirmed fix in perl version 5.12.0 ($VERSION of diagnostics.pm is 1.19)

Comment on diagnostics masks "uninitialized value in range (or flip)" warning
Select or Download Code
Re: diagnostics masks "uninitialized value in range (or flip)" warning
by ikegami (Pope) on Dec 08, 2009 at 15:53 UTC

    I plan to submit this patch as a bug report via perlbug:

    Excellent! It could use a test to make sure the current behaviour isn't reintroduced.

Re: diagnostics masks "uninitialized value in range (or flip)" warning
by Anonymous Monk on Dec 08, 2009 at 16:34 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://811761]
Approved by moritz
Front-paged by almut
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2014-04-19 21:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (483 votes), past polls