为什么添加或删除换行符会改变perl for for循环函数的方式?

时间:2010-08-10 01:48:33

标签: perl for-loop newline

我开始使用Wrox Beginning Perl available on perl.org学习perl,并对第3章中提供的for循环示例提出疑问。

#!/usr/bin/perl

use warnings;
use strict;

my @count = (1..10);
for (reverse(@count)) {
        print "$_...\n";
        sleep 1;
}
print "Blast Off!\n"

这是他们提供的脚本,它按预期工作。它显示一个数字,然后是......每秒钟,在每个数字之间等待一秒钟。完成后,会显示Blast Off!

但是,如果从print语句中删除换行符,则行为会发生变化。该脚本静默等待10秒钟,然后立即显示所有10个数字和Blash Off!。为什么要改变?

#!/usr/bin/perl

use warnings;
use strict;

my @count = (1..10);
for (reverse(@count)) {
        print "$_...";
        sleep 1;
}
print "Blast Off!\n"

4 个答案:

答案 0 :(得分:11)

Perl正在缓冲print输出,并且直到换行符才刷新缓冲区。或者,您可以在循环之前添加$| = 1以告诉Perl刷新print语句之间的缓冲区,从而为您提供具有适当延迟的预期输出:

#!/usr/bin/perl

use warnings;
use strict;

$| = 1; #Add this line
my @count = (1..10);
for (reverse(@count)) {
        print "$_...";
        sleep 1;
}
print "Blast Off!\n"'

答案 1 :(得分:4)

标准输出是行缓冲的。在看到换行符之前,它不会刷新缓冲区。您可以通过在循环之前添加以下行来更正此问题:

my $ofh = select(STDOUT); $| = 1; select $ofh;

让我们打破这一点:

my $ofh = select(STDOUT); - 选择STDOUT(标准输出)作为当前选定的文件句柄,并存储$ofh

中先前选择的文件句柄的内容

$| = 1; - 将当前文件句柄(即STDOUT)设置为无缓冲。

select $ofh; - 重新选择之前选择的文件句柄,这样如果代码在某个时刻选择了STDOUT以外的文件句柄,那么在完成这行代码后仍然会选择它。

答案 2 :(得分:4)

您正在查看写入终端时C stdio库的面向行的输出的标准行为。

有关perl的详细信息,请参阅autoflush

答案 3 :(得分:1)

比使用select()在STDOUT上设置autoflush标志更简洁的方法是使用IO :: Handle(自版本5.004以来已包含在Perl核心中):

use IO::Handle;
STDOUT->autoflush(1)