2014-11-17 2 views
1

Пожалуйста, посмотрите ниже. Файл содержит test.csvстранное поведение объявления массива в perl

aa,OPEN,TEMP1 
bb,CLOSE,TEMP2 
cc,OPEN,TEMP3 
dd,TERMINATED,TEMP4 

Код:

use Data::Dumper; 
sub main { 
    my $file = 'test.csv'; 
    my @lines1; 
    my @values; 

    unless (open (INPUT, $file)) { 
     print " files does not exist"; 
    } 
    while (my $line = <INPUT>) {     
     @values = split /\s*,\s*/, $line;  
     push @lines1, \@values; 
    } 
    foreach my $rr(@lines1) { 
     print Dumper ($rr)."\n"; 
    } 
    close INPUT; 
} 
main(); 

КОД РЕЗУЛЬТАТ:

$VAR1 = [ 
      'dd', 
      'TERMINATED', 
      'TEMP4 
' 
     ]; 

$VAR1 = [ 
      'dd', 
      'TERMINATED', 
      'TEMP4 
' 
     ]; 

$VAR1 = [ 
      'dd', 
      'TERMINATED', 
      'TEMP4 
' 
     ]; 

$VAR1 = [ 
      'dd', 
      'TERMINATED', 
      'TEMP4 
' 
     ]; 

Теперь, когда я запускаю код все, что я получаю последняя строка печатается в 4 раза. но я объявляю массив @values внутри цикла все работает отлично. Может кто-нибудь, пожалуйста, объясните мне это странное поведение.?

Благодаря

+0

Определение переменных в наименьшей сферы возможно, 'мои @values ​​= разделить/\ с *, \ s * /, $ строка,' как '@ values' не должны быть видны снаружи' while' петля , и в качестве побочного эффекта вы избавляетесь от нежелательного поведения. –

+0

Этот побочный эффект или ошибка или правильное поведение ..? что это такое? потому что я больше пишу, а не добавляю значения в массиве каждый цикл. , так что я верю, что он заполняет значения, а затем в следующий раз, когда он его перезаписывает? это правильно? – Nomad

+0

Это правильное поведение, поскольку вы всегда ссылаетесь на ту же переменную/(расположение памяти) '@ values' array =>' print \ @values, "\ n"; ' –

ответ

3

Ваша проблема в том, что у вас есть только один массив @values, и каждый раз, когда вы выполняете цикл, вы просто перезаписываете значения в том же массиве. Таким образом, вы получаете несколько ссылок на тот же массив, который содержит последний набор значений, которые вы вложили в него.

Одним из решений является создание нового массива @values каждый раз, когда вы обходите цикл.

while (my $line = <INPUT>) {    
    my @values = split /\s*,\s*/, $line; 
    push @lines1, \@values; 
} 

Другой альтернативой является взять копию массива и нажать эту ссылку на @lines1.

while (my $line = <INPUT>) {    
    my @values = split /\s*,\s*/, $line; 
    push @lines1, [ @values ]; 
} 
3

Причина заключается в том, что при объявлении @values в начале это одно и то же значение массива. Поэтому вы берете ссылку на тот же массив, чтобы каждый цикл перезаписывал предыдущее объявление. Однако, если вы объявляете массив в цикле, то в wnd каждой итерации массив выпадает из области действия amd больше не указывает на значение. Затем во время следующей итерации массив будет обновлен с новым значением.

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