2012-08-28 7 views
6

Я получаю предупреждение, запускающее один из моих сценариев Perl. Ошибка вызывается простым оператором if, где я тестирую, если строка в массиве равна другой строке.Неинициализированное значение в String 'eq' Perl

Моя коллега и я пробовали несколько сценариев и до сих пор не смогли разрешить предупреждения. Я попытался разместить все мои исследования до сих пор в этой теме, поэтому он немного длинный, но, пожалуйста, придерживайтесь его. Я полностью застрял и надеюсь, что один из великих умов Stack   Overflow может помочь мне!

код генерации проблем является:

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

Блок кода вокруг этого раздела является:

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

Моя цель в коде выше, чтобы назначить все переменные я нашел в текстовом файле в соответствующие переменные Perl. Затем я вставляю найденные переменные в базу данных SQL.

Текстовый файл имеет несколько полей, которые могут быть в разных порядках, поэтому я использую стиль switch if-elsif ... для выполнения присвоения значений. Есть также некоторые поля, которые меня не волнуют, такие как Level, и я просто игнорирую эти поля. Эти поля, однако, являются полями, которые вызывают предупреждения.

$var устанавливается на следующее, как он перебирает ...

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

Когда я нажимаю «Level = 0», то я могу сделать паузу в отладчике PerlIDE.exe и увидеть, что строка расщепляется на уровень и 0 и вставлен в массив. Однако, как только код переходит к заявлению if и проверяет $pieces[0] eq "PromotionNumber", я получаю предупреждение.

Я могу даже распечатать $ pieces [0] прямо перед оператором if, и он напечатает «Уровень».

Если изменить код на следующее предупреждение уходит ...

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 

Однако, если я проверить на «уровне» строка второго, предупреждение возвращается. Код ниже ПРЕДУПРЕЖДЕНИЕ.

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 

Почему Perl заботится о том, какой заказ я тестирую? Обратите внимание, что я тестирую НЕСКОЛЬКО другие строки, которые являются множественными elsif's в моих заявлениях if-elsif, которые не дают этого предупреждения.

Любые идеи? Мне действительно нужно очистить это предупреждение, чтобы оно не заливало консоль при запуске. Однако скрипт работает с предупреждениями.

Точная ошибка:

Использование неинициализированного значения в строке экв на japdpmrijob.pl линии 250.

Точная линия ошибок (определяется с помощью отладки утилиты Perl, в PerlIDE.exe):

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

Я могу распечатать $ pieces [0] и посмотреть значение. Поэтому я знаю, что это определено с моей стоимостью. Я также могу распечатать $ pieces [1] и увидеть ожидаемое значение. Если сначала проверить на $ pieces [0] eq «Уровень», предупреждение уходит, и я могу получить доступ к обеим переменным.

Я до сих пор путаю ...

Похоже, что ошибка на самом деле «эк» быть помечен как переменная. Есть идеи по этому поводу?

Ниже вы найдете большой фрагмент кода. Я включил весь цикл for и несколько переменных, с которыми я работаю. Обратите внимание на инструкцию else в конце последовательности if-elsif-else, я добавил ее, чтобы попытаться остановить предупреждение, как указано в третьем ответе. Этот оператор else печатает мои ожидаемые значения каждый раз, когда вызывается предупреждение, поэтому я знаю, что значения присутствуют.

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

Почти наверняка проблема заключается в выражении '$ pieces [1]', а не '$ pieces [0]'. Если у вас есть значение '$ var' без' = '(например, пустая строка),' split' вернет список одного элемента. Ваши тесты для «Тип» и «Уровень» смотрят только на первый элемент и будут работать, но блок под «PromotionNumber» пытается посмотреть на несуществующий второй элемент и генерирует предупреждение. –

+1

Пожалуйста, сообщите точную ошибку, которую вы получаете. Неясно, какая именно линия вызывает проблему. – chepner

+0

Кроме того, было бы возможно показать нам больше кода (по крайней мере цикл for, который устанавливает значение '$ var'). Это очень странная проблема. – chepner

ответ

9

Я думаю, вы ищете ошибку в неположенном месте. Для предупреждения, вызванного внутри оператора if-elsif-else или другого сложного блока кода, более старые версии Perl могут идентифицировать предупреждение как имеющее место в первой строке инструкции.

------ 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

У нас есть еще внизу, что должно быть «поймать всех».Я должен был на короткое время отправить код. Но, мои коллеги и я посчитали, что код может быть в другом месте, но мы достаточно уверены, что он находится в комбинации тестов «if-elsif». – Kyle

+1

На основании вашего ввода кажется, что вы столкнулись с линией «Level = 0», прежде чем столкнетесь с линией «ItemType». Это означает, что когда вы нажимаете окончательное предложение 'elsif',' $ itemTypeVar' еще не определено. И, как указывает @mob, это предупреждение, вероятно, будет связано с первоначальным предложением вашего большого оператора 'if-elsif-else'. – chepner

+0

@chepner СПАСИБО СМОТРЕТЬ! Я пошел дальше, и я ответил, что ответ мобов верен, но, вероятно, я был бы глуп, чтобы понять, что это была совершенно другая переменная, вызывающая мою ошибку. Я не знаю, почему я так и не подумал протестировать эту переменную. Проверяя, что $ itemTypeVar был определен до тестирования против него, все ошибки исчезли. Огромное спасибо всем! – Kyle

2

Вы можете проверить, не определено ли значение $pieces[0], прежде чем выполнять сравнения. В большинстве случаев это предотвратит предупреждение:

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

Я попытался добавить 'if (определено ($ pieces [0])) {print" DEFINED! "; } else {print "NOT DEFINED!"; } 'перед запросом if. Он распечатывается для каждого отдельного теста, включая мои тестовые тесты, а затем дает мне предупреждение о 'if ($ pieces [0] eq" PromotionNumber ") {' строка кода. Я полностью в тупике, о чем жалуется Perl! – Kyle

+2

Начиная с Perl 5.10, оператор '//' заменяет 'defined ...? ...: 'construction у вас есть -' my $ label = $ pieces [0] // '' ' – mob

+0

@mob, котор нужно знать. Я застрял с использованием 5.8.6, поэтому я немного отстаю в этих типах тонкостей. – scrappedcola

Смежные вопросы