Re: Tracking down uninitialized values...
by philcrow (Priest) on Jul 28, 2006 at 15:56 UTC
|
| [reply] |
|
You're right. On many that I've been fixing I was able to use the line number to fix it, however, this one has me stumped so I intentionally left out the additional info it gives in hopes of finding general answers for how to track them down vs. this specific instance. Though since I've mentioned it now, here's the full message: "Use of uninitialized value in join or string at (eval 39) line 15."
Thanks for the quick response!
| [reply] |
|
use warnings;
foreach my $i ( 1..5, undef, 7..9 ) {
eval '$x = join("",$i,"");';
}
# Use of uninitialized value in join or string at (eval 6) line 1.
| [reply] [d/l] |
|
| [reply] |
Re: Tracking down uninitialized values...
by rodion (Chaplain) on Jul 28, 2006 at 16:30 UTC
|
My experience is that once you get to the harder cases of uninitialized values, they are caused by variables where you stare at the it and think, "well that has to be there", and you later find out that it's not. The solution is to check each parameter at the entry to each function to see if it's defined, and kick off a warning or a die if it should be defined and isn't. It's tedious to write, and it interupts the flow when you're reading the code, but it saves lots of grief, IMO.
It's also useful to have those checks in there when something changes with the data and the routine blows up, 6 months down the road. | [reply] |
|
Both good suggestions (the above and the higher up about finding that certain eval). It seems like if the problem ends up being in a module that's being called it would be MUCH more difficult to track down by putting checks in the local code unless I played the elimination game of removing lines until the problem goes away.
I thought I had read the debugger had a mode that would basically allow me to step through the program and see what happens as it executes. I was hoping I could use something like that to watch for exactly where/what it was complaining about.
Time to visit the friendly manual some more. ;)
| [reply] |
Re: Tracking down uninitialized values...
by imp (Priest) on Jul 28, 2006 at 18:32 UTC
|
use strict;
use warnings;
use Carp;
# Configure the warn signal handler to print the stack trace provided
+by Carp.
$SIG{__WARN__} = sub {print STDERR Carp::longmess(@_); };
run();
sub run {
my $code = eval 'sub {
my $a = 1 - undef;
};';
$code->();
}
The output is:
Use of uninitialized value in subtraction (-) at (eval 1) line 2.
main::__ANON__() called at pm564376.pl line 14
main::run() called at pm564376.pl line 8
| [reply] [d/l] [select] |
Re: Tracking down uninitialized values...
by kwaping (Priest) on Jul 28, 2006 at 17:15 UTC
|
| [reply] [d/l] |
|
Nice tip! Using that I was able to pinpoint from where the complaint was coming and fix it. It's not the elegant solution I was hoping for, but it worked and the problem's solved so how can I complain? ;)
For those who are interested, here's the offending line of code causing 5MB of that warning:
map{ td({align=>$align->{$_} || $default_align, valign=>$default_valig
+n}, $main_row->{$_}) } @summary_columns;
Only a couple of thousand more lines like that hidden around this massive system to deal with now. :P | [reply] [d/l] |
Re: Tracking down uninitialized values...
by starbolin (Hermit) on Jul 28, 2006 at 17:32 UTC
|
I have seen a lot of examples where the programmer created this problem by not checking return values. He does a call to a system function or a module function then uses the return value without testing for undef or false. These errors can propagate quite a ways through the code through various regexes and other manipulations. No, I don't know of any automated way of checking this. You need to check the documentation for each call for possible return values. Defensive programming is the word here. Every call returning a string or reference should be checked for both undef and null.
s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s
|-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,,
$|=1,select$,,$,,$,,1e-1;print;redo}
| [reply] [d/l] |
A reply falls below the community's threshold of quality. You may see it by logging in. |