2016-07-28 21 views
2

我有一個多維散列,其中包含打開的文件句柄SEEK_END,目的是始終讀取最新的行,而不需要太多的I/O(我會用tail )。(空?)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似乎並沒有確定的readlineundef爲空空回 - 它只是打印什麼,這是對的,因爲這個字符串中沒有任何內容,但我不希望它被處理。

+0

聖潔鱷梨醬。非常感謝你。似乎最簡單的答案是最好的。我嘗試了很多奇怪的東西,從來沒有把注意力放在'||'操作符上。我愚蠢。現在工作正常。 – David

+0

用'或'代替它確實很好,但我對於評估順序進行了糾正 - 請參閱[Borodin](http://stackoverflow.com/users/622310/borodin)的答案。請參閱['perlop中的運算符優先級](http://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity) – zdim

+0

另請參見[Perl的「not」運算符未按預期方式與定義的()功能](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 ''部分

它通常是更安全使用優先級較低的andornot而不是&&||!但混合是一個非常糟糕的主意

你可以寫任何

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

這種事情也傾向於保持嵌套塊下我覺得這提高了代碼的可讀性的數量。