我已经开始玩perl了,我正试图弄清楚如果我也提供循环,那么告诉perl
使用循环有什么错?
看起来perl与相同的打开文件描述符混淆了,但我不明白为什么它会吃掉第一行?
perl -ne 'while (<>) { print $_; }'
当然,在这个简单的例子中,我可以简单地perl -ne '{print $_}'
来获得相同的功能逻辑。
但我想知道的是,如果另一个while (<>) { }
被包裹,第一行消失的双循环出了什么问题?
$ perl -ne '{print $_}' hello
hello
hello
world
world
^C
$ perl -ne 'while (<>) { print $_; }'
hello
world
world
^C
更新:根据答案,似乎正在发生的事情是Perl正在等待STDIN输入的第一个循环。在接收到STDIN上的输入时,该输入被分配给内部缓冲器$_
,并且逻辑前进到第二循环,在第二循环中再次等待新的STDIN输入。在接收到新的STDIN输入时,它用新的STIN输入冲击STDIN缓冲器$_
并开始打印。
您可以自己使用O=Deparse
检查一个行生成的代码。
第一个:
$ perl -MO=Deparse -ne 'print $_;' file
LINE: while (defined($_ = <ARGV>)) {
print $_;
}
-e syntax OK
第二:
$ perl -MO=Deparse -ne 'while (<>) { print $_; }' file
LINE: while (defined($_ = <ARGV>)) {
while (defined($_ = <ARGV>)) {
print $_;
}
}
-e syntax OK
现在,很容易知道第二种情况出了什么问题。外层吃掉了文件的第一行,文件丢失了。
-n
标志将代码封装在while (<>) { ... }
构造中。
所以在第二个例子中,实际执行的代码是
while (<>) # reads a line from STDIN, places it in $_
{
# you don't do anything with the contents of $_ here
while (<>) # reads a line from STDIN, places it in $_, overwriting the previous value
{
print $_; # prints the contents of $_
}
}
这意味着第一个<>
读取的行刚刚丢失。