我通常是通過使用下面的代碼文件中的行循環:使用Perl循環遍歷文件中的行最具防禦性的方法是什麼?
open my $fh, '<', $file or die "Could not open file $file for reading: $!\n";
while (my $line = <$fh>) {
...
}
然而,in answering another question,Evan Carroll編輯我的回答,改變我的while
聲明:
while (defined(my $line = <$fh>)) {
...
}
他的理由是,如果你有一條線是0
(它必須是最後一行,否則它將有回車),那麼如果您使用我的聲明,您的while
會過早退出($line
將設置爲"0"
,並且來自分配的返回值因此也將是"0"
,其被評估爲假)。如果你檢查定義,那麼你不會遇到這個問題。它非常有意義。
所以我試了一下。我創建了一個文本文件,其最後一行是0
,沒有回車。我在循環中運行它,並且循環沒有過早退出。
然後我想,「啊哈,也許這個價值並不是實際的0
,也許還有別的東西在搞砸了!所以我用Dump()
從Devel::Peek
,這是它給了我:
SV = PV(0x635088) at 0x92f0e8
REFCNT = 1
FLAGS = (PADMY,POK,pPOK)
PV = 0X962600 "0"\0
CUR = 1
LEN = 80
這似乎在告訴我,值實際上是字符串"0"
,因爲我得到了類似的結果,如果我叫Dump()
上標I」已明確設置爲"0"
(唯一的區別在於LEN字段 - 從文件LEN是80,而標量LEN是8)。
那麼有什麼交易?爲什麼我的while()
循環沒有提前退出,如果我通過一條只有"0"
且沒有回車符的行? Evan的循環實際上更具防禦性,還是Perl在內部做了一些瘋狂的事情,這意味着你不需要擔心這些事情,而while()
實際上只有在你點擊eof
時纔會退出?
如果你正在尋找防守代碼,使用[坦克]( http://en.wikipedia.org/wiki/Tank)。 – 2010-09-22 22:02:48
這就是爲什麼我不會編輯某人回覆的意思(我只是修復明顯的錯別字)。如果您認爲有遺漏或可以改進,請添加評論。並感謝您調查內部! – Ether 2010-09-22 22:08:56