Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uninitialized Value in String 'eq' Perl

I'm getting a warning running one of my Perl scripts. The error is being thrown at a simple if statement where I'm testing if a string in an array is equal to another string.

My coworker and I have tried several scenarios and still haven't been able to resolve the warnings. I've tried to place all my research so far into this thread, so it is a little long, but please stick with it. I'm completely stuck and hoping one of the great minds of Stack Overflow can help me out!

The code generating the problems is:

if ($pieces[0] eq "PromotionNumber")

The block of code around that section is:

my @pieces = split(/=/, $var);
if($pieces[0] eq "PromotionNumber") {
     $promoNumber = $pieces[1];
} elsif ($pieces[0] eq "Type") {
# More similar code follows

My goal in the above code is to assign all the variables I've found in a text file to the respective Perl variables. I then insert those found variables into a SQL database.

The text file has several fields that can be in different orders, which is why I use the switch style if-elsif... to accomplish assigning values. There are also some fields I don't care about, such as Level, and I just ignore these fields. These fields however are the fields that cause warnings.

The $var is set to the following as it loops through...

PromotionNumber=000
RecordOffset=0
Code=0
SubCode=1
Level=0

When I hit "Level=0", I can pause in the PerlIDE.exe debugger and see that the string is split into Level and 0 and inserted in the array. However, as soon as the code advances to the if statement and tests $pieces[0] eq "PromotionNumber" I get the warning.

I can even print out $pieces[0] right before the if statement, and it will print "Level".

If I change the code to the following the warning goes away...

my @pieces = split(/=/, $var);
if($pieces[0] eq "Level") {
    #My problematic variable test
}elsif($pieces[0] eq "PromotionNumber") {
     $promoNumber = $pieces[1];
} elsif ($pieces[0] eq "Type") {
#More similar code follows

However, if I test for the "Level" string second, the warning comes back. The code below DOES have the warning.

my @pieces = split(/=/, $var);
if($pieces[0] eq "PromotionNumber") {
    #My problematic variable test
}elsif($pieces[0] eq "Level") {
     $promoNumber = $pieces[1];
} elsif ($pieces[0] eq "Type") {
#More similar code follows

Why does Perl care which order I test in? Note, that I am testing SEVERAL other strings that are multiple elsif's down in my if-elsif statements that don't give this warning.

Any ideas? I really need to clear up this warning so that it doesn't flood the console when running. The script is working with the warnings though.

Exact error is:

Use of uninitialized value in string eq at japdpmrijob.pl line 250.

Exact line of error (determined using Perl's debug utility in PerlIDE.exe) is:

if ($pieces[0] eq "PromotionNumber") {

I can print out $pieces[0] and see the value. So I know it is defined with my value. I can also print out $pieces[1] and see my expected value. If I test for $pieces[0] eq "Level" first, the warning goes away and I can access both variables.

I am still confused...

It looks like the error is actually the "eq" being flagged as a variable. Any ideas on that?

Below you'll find a large chunk of the code. I included the entire for loop and several of the variables that I'm working with. Notice the else statement at the end of the if-elsif-else sequence, I added this to attempt stop the warning as noted by the third answer. This else statement prints my expected values every time the warning is called, so I know the values are present.

for my $cond (@conditions) {
    if($debug==1){print $cond."\n";}

    # Required database variables
    my $isRecord = 0;
    my $promoNumber;
    my $type;
    my $process;
    my $testValue;
    my $recordOffset;
    my $code;
    my $subcode;
    my $itemType;
    my $itemValue;

    # Function test variables
    my $itemTypeVar;
    my $newQualifier = 1;

    # Database Configuration
    my $dbApps = new Win32::ODBC("myDatabase") || die "Error: " . Win32::ODBC::Error();
    my @condVars = split(/\|/, $cond);
    for my $var (@condVars) {
        if($debug==1){print $var."\n";}
        my @pieces = split(/=/, $var);
        if( defined($pieces[0]) ){
            print "piece 0 defined!\n";
        } else {
            print "pieces 0 not defined!\n";
        }
        if( defined($pieces[1]) ){
            print "piece 1 defined!\n";
        } else {
            print "piece 1 not defined!\n";
        }
        if($pieces[0] eq "PromotionNumber"){
            $promoNumber = $pieces[1];
        } elsif ($pieces[0] eq "Type"){
            $type = $pieces[1];
        } elsif ($pieces[0] eq "Process"){
            $process = $pieces[1];
        } elsif ($pieces[0] eq "TestValue"){
            $testValue = $pieces[1];
        } elsif ($pieces[0] eq "RecordOffset"){
            $recordOffset = $pieces[1];
            if ($recordOffset == 0) {
                $newQualifier = 1; }
        } elsif ($pieces[0] eq "Code"){
            $code = $pieces[1];
        } elsif ($pieces[0] eq "SubCode"){
            $subcode = $pieces[1];
        } elsif ($pieces[0] eq "ItemType"){
            $itemType = $pieces[1];
            if($itemType eq "0") {
                $itemTypeVar = "ItemCode";
            } elsif($itemType eq "1") {
                $itemTypeVar = "ItemCode";
            } elsif($itemType eq "2") {
                $itemTypeVar = "Department";
            } elsif($itemType eq "5") {
                $itemTypeVar = "MixMatchCode";
            } elsif($itemType eq "12") {
                $itemTypeVar = "GroupCode";
            }
        } elsif ($pieces[0] eq $itemTypeVar){
            $itemValue = $pieces[1];
        } else {
            print "$pieces[0] and $pieces[1] not used.\n";
        }
        print "$var\n";
    }
}
like image 703
Kyle Avatar asked Aug 28 '12 19:08

Kyle


1 Answers

I think you are looking for the error in the wrong place. For a warning triggered inside an if-elsif-else statement or other complex block of code, older versions of Perl may identify the warning as occuring on the first line of the statement.

------ warn.pl ------
my $x = 0;
my $y;
if ($x == 1) {         # line 3
} elsif ($x == 2) {
} elsif ($x == 3) {
} elsif ($y == 4) {    # line 7
}

$ perl5.14.2 -w warn.pl
Use of uninitialized value $y in numeric eq (==) at warn.pl line 7.

$ perl5.8.6 -w warn.pl
Use of uninitialized value in numeric eq (==) at line 3.
like image 86
mob Avatar answered Oct 18 '22 11:10

mob