我是Perl的新手,在逐行读取文件时遇到问题。我从一个建议使用while循环的教程开始。这工作正常,但我想有一个选项,以便在出现错误时突破循环。我知道我可以使用“last”关键字,但我不太喜欢它,我想将它包含在while循环的布尔表达式中,以便更容易看到它停止的条件。所以我做了
$error=0;
while ( (!$error) && (<MYFILE>) ) {
print $_;
...
}
不幸的是,这不起作用,因为$ _似乎包含“未初始化的值”。出于某种原因,当我将(!$ error)更改为(!0)时,它再次起作用。如果我使用了||,我会理解它不起作用因为懒惰的评价,但与&amp;&amp;在这种情况下,需要对双方进行评估,因此我不明白它为什么不初始化行变量。
答案 0 :(得分:5)
只有在循环中没有其他内容时才会发生$_
的神奇分配:
while (<MYFILE>) {
print $_;
...
}
如果您也想要进行错误测试 - 这是不推荐的 - 那么您需要进行分配:
my $error = 0;
while (!$error && ($_ = <MYFILE>)) {
print;
$error = 1 if m/quit/i;
}
不要忘记添加:
use warnings;
use strict;
“!0
”版本的工作原因可能是因为Perl优化并认识到“!0
”始终为真,并将其从循环中删除,只留下I / O运算符,然后分配给$_
。
注意:使用惯用的Perl和last
语句要好得多:
while (<MYFILE>) {
print;
last if m/quit/i;
}
答案 1 :(得分:3)
首先,正如乔纳森所指出的那样,除非你有充分的理由,否则你应该总是以惯用的方式编写语言。
你的大问题是误解了while
循环。只有在$_
条件测试中,角度运算符的结果才会自动分配给while
。如果条件测试中有多个项目,则对它们进行评估然后丢弃( Programming Perl pp.80-81 and I/O Operators at Perldoc)。