我开始使用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"
答案 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)