2012-08-28 13 views
6

Recibo una advertencia al ejecutar uno de mis scripts de Perl. El error se produce en una simple declaración if donde estoy probando si una cadena en una matriz es igual a otra cadena.Valor no inicializado en cadena 'eq' Perl

Mi compañero de trabajo y yo hemos intentado varios escenarios y todavía no hemos podido resolver las advertencias. Intenté ubicar toda mi investigación hasta el momento en este hilo, por lo que es un poco larga, pero por favor, apéguenme. Estoy completamente atascado y espero que una de las grandes mentes de Stack   Overflow pueda ayudarme.

El código que genera los problemas es:

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

El bloque de código alrededor de esa sección es:

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

Mi objetivo en el código anterior es asignar todas las variables que he encontrado en un archivo de texto a las variables de Perl respectivas. Luego inserto esas variables encontradas en una base de datos SQL.

El archivo de texto tiene varios campos que pueden estar en diferentes órdenes, por lo que utilizo el estilo de cambio if-elsif ... para lograr la asignación de valores. También hay algunos campos que no me importan, como Level, y simplemente ignoro estos campos. Sin embargo, estos campos son los campos que causan advertencias.

El $var se establece en la siguiente, ya que recorre ...

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

Cuando golpeo "Nivel = 0", puedo hacer una pausa en el depurador PerlIDE.exe y ver que la cadena se divide en Level y 0 e insertado en la matriz. Sin embargo, tan pronto como el código avanza a la declaración if y prueba $pieces[0] eq "PromotionNumber" aparece la advertencia.

Incluso puedo imprimir $ pedazos [0] justo antes de la declaración if, y se imprimirá "Nivel".

Si cambio el código para la siguiente advertencia desaparece ...

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 

Sin embargo, si el test para el "Nivel" cadena segundos, la advertencia vuelve. El código siguiente tiene la advertencia.

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 

¿Por qué a Perl le importa qué orden realizo la prueba? Tenga en cuenta que estoy probando VARIAS otras cadenas que son múltiples elsif abajo en mis declaraciones if-elsif que no dan esta advertencia.

¿Alguna idea? Realmente necesito aclarar esta advertencia para que no inunde la consola cuando se está ejecutando. Sin embargo, el script está trabajando con las advertencias.

error exacta es:

Uso del valor no inicializado en eq cadena en línea japdpmrijob.pl 250.

línea exacta de error (determinado usando la utilidad de depuración de Perl en PerlIDE.exe) es:

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

Puedo imprimir $ pieces [0] y ver el valor. Entonces sé que está definido con mi valor. También puedo imprimir $ pieces [1] y ver mi valor esperado. Si primero pruebo $ pieces [0] eq "Level", la advertencia desaparece y puedo acceder a ambas variables.

Todavía estoy confundido ...

Parece que el error es en realidad el "eq" está marcado como una variable. Alguna idea sobre eso?

A continuación encontrará una gran parte del código. Incluí todo el ciclo for y varias de las variables con las que estoy trabajando. Observe la declaración else al final de la secuencia if-elsif-else, la agregué para intentar detener la advertencia como lo señala la tercera respuesta. Esta instrucción else imprime mis valores esperados cada vez que se invoca la advertencia, por lo que sé que los valores están presentes.

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"; 
    } 
} 
+0

Casi con certeza, el problema es la expresión '$ pieces [1]', no '$ pieces [0]'. Si tiene un valor de '$ var' sin un' = '(una línea en blanco, por ejemplo)' split' devolverá una lista de un solo elemento. Sus pruebas para "Tipo" y "Nivel" solo miran el primer elemento y funcionarán, pero el bloque debajo de "PromotionNumber" intenta mirar el segundo elemento inexistente y genera la advertencia. –

+1

Por favor, publique el error exacto que está recibiendo. No está claro exactamente qué línea está causando el problema. – chepner

+0

Además, ¿sería posible mostrarnos más del código (al menos el ciclo for que establece el valor de '$ var'). Este es un problema muy extraño. – chepner

Respuesta

9

Creo que está buscando el error en el lugar equivocado. Para una advertencia activada dentro de una declaración if-elsif-else u otro bloque complejo de código, las versiones anteriores de Perl pueden identificar la advertencia como que ocurre en la primera línea de la instrucción.

------ 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. 
+0

Tenemos un else en la parte inferior que debería ser una "catch-all".Debería tener el código publicado momentáneamente. Pero, mis compañeros de trabajo y yo hemos considerado que el código podría estar en otra parte, pero estamos bastante seguros de que está en la combinación de pruebas "si-elsif". – Kyle

+1

Según su entrada, parece que se encuentra con la línea "Nivel = 0" antes de encontrar una línea "Tipo de artículo". Esto significa que cuando tocas la cláusula final de 'elsif', '$ itemTypeVar' aún no está definido. Y como señala @mob, esta advertencia probablemente se atribuirá a la cláusula inicial de su gran declaración 'if-elsif-else'. – chepner

+0

@chepner ¡MUCHAS GRACIAS! Seguí adelante y marqué la respuesta de la mafia como correcta, pero probablemente habría sido estúpido al descubrir que era una variable completamente diferente que causaba mi error. No sé por qué no pensé en probar esa variable también. Al verificar que $ itemTypeVar se definió antes de realizar pruebas en su contra, todos los errores desaparecieron. ¡Muchas gracias a todos! – Kyle

2

Puede comprobar si se define $pieces[0] antes de hacer comparaciones. La mayoría de las veces esto evitará la advertencia:

my @pieces = split(/=/, $var); 
my $label = defined($pieces[0]) ? $pieces[0] : ""; #if not defined init to "" 
my $value = defined($pieces[1]) ? $pieces[1] : ""; 
if($label eq "PromotionNumber") { 
    $promoNumber = $value; 
} elsif ($label eq "Type") { 
#More similar code follows 
+0

Intenté agregar 'if (defined ($ pieces [0])) {print" DEFINED! "; } else {print "¡NO DEFINIDO!"; } 'justo antes de la declaración if problemática. Imprime definido para cada prueba, incluidas las pruebas de mi problema, y ​​aún así me da una advertencia sobre la línea de código 'if ($ pieces [0] eq PromotionNom)" {'. ¡Estoy completamente perplejo sobre lo que Perl se está quejando! – Kyle

+2

Desde Perl 5.10, el operador '//' reemplaza al 'definido ...? ...: 'construcción que tiene -' my $ label = $ pieces [0] // '' ' – mob

+0

@mob es bueno saberlo. Estoy atascado con el uso de 5.8.6, así que estoy un poco rezagado en ese tipo de detalles. – scrappedcola

Cuestiones relacionadas