Re: Is this a severe error?
by choroba (Cardinal) on Jun 03, 2015 at 14:46 UTC
|
It's not an error, it's a warning, as splain can tell you:
$ splain <<< 'Use of uninitialized value in concatenation (.) or strin
+g in line 1245'
Use of uninitialized value in concatenation (.) or string in line 1245
+ (#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 will try to tell y
+ou the
name of the variable (if any) that was undefined. In some cases it
+ cannot
do this, so it also tells you what operation you used the undefine
+d value
in. Note, however, that perl optimizes your program and the opera
+tion
displayed in the warning may not necessarily appear literally in y
+our
program. For example, "that $foo" is usually optimized into "that
+ "
. $foo, and the warning will refer to the concatenation (.) operat
+or,
even though there is no . in your program.
It seems more probable that the warnings came from the print line, as it contains more concatenations than the assignment.
| [reply] [d/l] [select] |
Re: Is this a severe error?
by AnomalousMonk (Archbishop) on Jun 03, 2015 at 15:02 UTC
|
... error in my code ...
As others have replied, it's not an error, it's a warning (see warnings, which you have wisely enabled in your program).
Where is it? The only line in the quoted code that does concatenation (or string interpolation, which is effectively the same thing) is
print PLP_FILE "$aa_pos\t".$split_query_for_PLP[$s]."\t".$hash_plp_lbl_barrel_region_only{$s}."\n";
It seems unlikely to be $aa_pos. My suspicious eye is drawn to the
$s<=(($start_of_barrel_region+$length_of_barrel_region))
expression in the for-loop test: is it possible you have an off-by-one error here? E.g., if $start_of_barrel_region were 0 and $length_of_barrel_region were the number of elements in the @split_query_for_PLP array, would not the <= comparison allow an index to be generated that was one element beyond the end of the array, and thus undefined? (I don't know about the rest of your code, and so don't know if anything like this could happen.) Just a guess.
Is it severe? If you are operating on meaningless data that you believe to be meaningful, it's severe.
Give a man a fish: <%-(-(-(-<
| [reply] [d/l] [select] |
Re: Is this a severe error?
by Athanasius (Archbishop) on Jun 03, 2015 at 15:07 UTC
|
As others have said, the message you’re getting is a warning, not an error, and it’s likely coming from the line:
print PLP_FILE "$aa_pos\t".$split_query_for_PLP[$s]."\t".$hash_plp_l
+bl_barrel_region_only{$s}."\n";
in which case either the array element $split_query_for_PLP[$s] or the hash element $hash_plp_lbl_barrel_region_only{$s} is undefined for some value(s) of $s.
For general debugging advice, see toolic’s Basic debugging checklist. In this case, something like this:
for (my $s = $start_of_barrel_region; $s <= (($start_of_barrel_region
++ $length_of_barrel_region)); $s++)
{
my $aa_pos = $s + 1;
warn "\$aa_pos is undefined when \$s is $s" unless d
+efined $aa_pos;
warn "\$split_query_for_PLP[$s] is undefined" unless d
+efined $split_query_for_PLP[$s];
warn "\$hash_plp_lbl_barrel_region_only{$s} is undefined" unless d
+efined $hash_plp_lbl_barrel_region_only{$s};
print PLP_FILE "$aa_pos\t".$split_query_for_PLP[$s] . "\t" . $hash
+_plp_lbl_barrel_region_only{$s} . "\n";
}
should solve the mystery.
Hope that helps,
| [reply] [d/l] [select] |
Re: Is this a severe error?
by GotToBTru (Prior) on Jun 03, 2015 at 14:55 UTC
|
If your program executes, that's a hint that this is just a warning, and not an error. Perl programs abort on errors (unless otherwise provided for).
Read the message - it is complaining about concatenation. More likely the error is in the print statement following. If $start_of_barrel_region is undefined, $s will be too, and so then $hash_plp_lbl_barrel_region_only{$s} will be undefined because the key is undefined. Once the loop body has executed once, the $s++ will make $s now be 1, and you won't see the warning again.
Use the debugger to inspect the values to make sure they are what you expect.
| [reply] |
Re: Is this a severe error?
by toolic (Bishop) on Jun 03, 2015 at 15:34 UTC
|
Did you expect the variable to be uninitialized? If not, then the warning message indicates a bug in your code. Regardless, you should fix your code to avoid the warning. Additionally, you could opt to make all warnings errors (Get stricter with use warnings FATAL => 'all';).
| [reply] |
Re: Is this a severe error?
by kcott (Archbishop) on Jun 03, 2015 at 18:49 UTC
|
use strict;
use warnings;
use diagnostics;
This pragma is a developer tool. Its output, which can be quite lengthy, is generally not suitable for end-users (too long, too technical, etc.) and it can swamp log files (messages you really want to see can become lost amongst all this verbiage).
My general advice is:
-
Only use this pragma while you are learning and having difficulty understanding the terse, one-line messages.
-
Remove the 'use diagnostics;' line from production code.
| [reply] [d/l] [select] |
Re: Is this a severe error?
by Laurent_R (Canon) on Jun 03, 2015 at 20:16 UTC
|
Quite often, this type of warning does not prevent you from getting the correct results. For example, it may be due to a file having an empty line at the bottom. You get this warning when you try to split the line and don't get the expected fields. This happens quite commonly. And you probably don't really care that much, your program works nonetheless.
But if you have it, it probably means that you are not inspecting your data close enough before using it. Although I might probably not care in a one-off one-liner, I would never leave such a warning in actual production code, even if the results are OK. Check your data before you use it, make sure it looks like what you expect, and raise an exception (or a warning) if it does not fit the bill.
Perl's strict and warnings pragmas, among others, help you writing more correct software, take advantage of it, don't hide the dust under the carpet.
Having said that, there are a very few cases where you might want to silence out some warnings. You can do that, if you really know what you're doing. There is at least one case where I remember having done it: the "deep recursion" warning tells you that you have entered more than 100 recursion levels. Sometimes it's OK if you have another way of controlling that the depth of recursion is not going run amok. But you really have to know damn well what you are doing. Judging from your question, you are not at that point yet.
| [reply] [d/l] [select] |
|
|
Dear Monks!
Thanks A LOT for all these posts... I looked in the code and, before all these, I have written:
my ($initial_label, $barrel_region, $start_of_barrel_region, $length_o
+f_barrel_region);
Wouldn't this "secure" that the $start_of_barrel_region is defined? Should I write something else? | [reply] [d/l] |
|
|
Wouldn't this "secure" that the $start_of_barrel_region is defined?
No, as you can easily verify:
#! /usr/bin/perl
use warnings;
use strict;
my $x;
print defined($x) ? "Defined\n" : "Undefined\n";
print $x;
my declares a variable, but doesn't make it defined. You have to assign a value to it (other than undef) to make it defined.
| [reply] [d/l] |
|
|
No, defined is not the same thing as declared.
With your my (...); statement, you have properly declared these variables, but they are still not defined because you haven't assigned any value to them.
Update: Oops, choroba was faster than me.
| [reply] [d/l] |
|
|
|
|
|