2016-07-28 2 views
2

У меня есть многомерный хеш, содержащий открытые дескрипторы файлов на SEEK_END с целью всегда читать последнюю строку, не получая много ввода-вывода (что бы я получил с tail).(пусто?) Return readline не пойман структурой управления

Теперь я просматриваю все эти ручки с помощью петли for и звоня по телефону readline.

Это выглядит следующим образом:

for $outer (keys %config) { 

    my $line = readline($config{$outer}{"filehandle"}); 

    if (not defined $line || $line eq ''){ 
     next; 
    } 
    else{ 
     print "\nLine: -->".$line."<--\n"; 
     $line =~ m/(:)(\d?\.?\d\d?\d?\d?\d?)/; 
     $wert = $2; 
    } 
} 

Если новое содержание записывается в эти файлы, мой сценарий читает и ведет себя так же, как и планировалось.

Проблема заключается в том, что readline будет обычно возвращают ничего, потому что нет в настоящее время ничто в конце файла, но мой if не кажется, чтобы определить пустое возвращение readline в undef как пустые - это просто ничего не печатает, который был бы прав, потому что в этой строке ничего нет, но я не хочу, чтобы он обрабатывался вообще.

+0

Священный guacamole. Большое спасибо. Похоже, самый простой ответ - лучший. Я пробовал так много странных вещей и никогда не смотрел на '' 'Operator. Глупый я прав. Сейчас работает отлично. – David

+0

Замена его на 'или' действительно прекрасна, но я стою исправлен относительно порядка оценок - см. Ответ [Бородин] (http://stackoverflow.com/users/622310/borodin). См. ['Приоритет оператора в perlop'] (http://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity) – zdim

+0

См. Также [Оператор« не »Perl не работает должным образом с определенным() функция] (https://stackoverflow.com/questions/12958603/perls-not-operator-not-working-as-expected-with-the-defined-function) –

ответ

6

Это проблема приоритета оператора. Вы использовали смесь низкого приоритета not с высоким приоритетом || так ваше состояние

not defined $line || $line eq '' 

обрабатывается как

not( defined($line) || ($line eq '') ) 

, который ошибочно отрицает $line eq '' часть

Это, как правило, безопаснее используйте нижние приоритеты и or и not по сравнению с &&, || и ! , Но смесь очень плохая идея

Вы можете написать либо

if (not defined $line or $line eq '') { 
    ... 
} 

или

if (! defined $line || $line eq '') { 
    ... 
} 

тогда все будет хорошо


Я бы предпочел, чтобы увидеть его написано так, потому что оно теряет ненужное предложение else и next операторов и отбрасывает строки, содержащие только пробельные символы

Также обратите внимание, что я перебираю по values хеша. Использование ключей бесполезно, если они используются только для доступа к значениям. Вы, вероятно, будете в состоянии придумать лучшее название для управления с обратной связью переменной $item

И там часто нет необходимости для оператора конкатенации, когда Perl будет интерполировать переменные непосредственно в двойные кавычки

for my $item (values %config) { 

    my $line = readline($item->{filehandle}); 

    if (defined $line and $line =~ /\S/) { 

     print "\nLine: -->$line<--\n"; 

     $line =~ m/(:)(\d?\.?\d\d?\d?\d?\d?)/; 
     $wert = $2; 
    } 
} 
1

Я инициатор простых условий. Если это вообще возможно, я избегаю сложных логических условий с другим, так что мне не нужно думать о наборе дополнений и т. Д.Таким образом, я бы перечислил условия пропуска индивидуально:

next unless defined $line; 
next unless $line =~ /\S/; 

Такого рода вещи также стремится сохранить количество вложенных блоков нижних, которые я нахожу улучшает читаемость кода.