今天在我的大学里,老师问我一个问题。他在纸上写下了这段代码并说 “这段代码的输出是什么?”
use warnings;
for (1 .. 20)
{
print ".";
}
我发现它很容易并且说它将循环20次,并且在每次迭代时它将打印一个点(。),因此总共20个点将是输出。
他说你是对的,然后他对代码做了一些修改。代码是:
use warnings;
for (1 .. 20)
{
print ".";
sleep 1;
}
他说现在输出的是什么?我不知道睡眠功能,我猜想在每次迭代时它会打印点(。)然后它会等待1秒(因为睡眠功能)然后它会再次迭代然后它会再次打印(。)然后它将等待1秒,依此类推......
老师叫我在家里检查一下。我在家尝试了,我发现第二个代码等了20秒,然后一次打印所有点(20个点)。我想知道这是怎么发生的?为什么点(。)在每次迭代时都没有打印?答案 0 :(得分:24)
真正的问题与sleep
无关,而是............
您是Suffering from Buffering 。所提供的链接将带您阅读大约1998年由Perc Journal撰写的优秀文章,来自Marc Jason Dominus(高阶Perl的作者)。这篇文章可能已有十多年的历史了,但今天的主题和他写这篇文章的时候一样重要。
其他人已经解释了$| = 1;
技术。我想补充一点,在Perl社区的主要思想中,似乎$| = 1
优于$|++
只是因为它的含义更清晰。我知道,自动增量也非常简单,但是当$|
或++
被应用时,每个看过代码的人都会知道--
的行为(而不是在use strict;
use warnings;
{
local $| = 1;
for ( 1 .. 20 ) {
print '.';
sleep 1;
}
}
查找3}})。我碰巧也喜欢本地化Perl的“特殊变量”的任何修改,以便效果不会冲到代码的其他部分,这些部分可能对默认的Perl行为的特定更改不起作用。既然如此,我会把它写成:
{{1}}
答案 1 :(得分:15)
Perl和许多其他程序,默认情况下是行缓冲输出。如果需要无缓冲输出,可以将$|
设置为1
。
答案 2 :(得分:12)
它没有清除缓冲区。如果print语句末尾有换行符,它将自动为您执行此操作:
use warnings;
for (1 .. 20) {
print ".\n";
sleep 1;
}
如果你不想要换行符(我不认为你这样做),你可以使用特殊的autoflush变量$|
。尝试将其设置为1
或递增它。
use warnings;
$|++;
for (1 .. 20) {
print ".";
sleep 1;
}