鉴于以下红宝石:
$i = 0
$num = 3
while $i < $num do
puts "My loop just executed"
sleep 10
$i +=1
end
我希望每10秒(加上执行时间)我会将“我的循环刚刚执行”打印到我的控制台,直到$ i = 3
My loop just executed
# sleeps for 10 seconds
My loop just executed
# sleeps for 10 seconds
My loop just executed
# sleeps for 10 seconds
然而,实际发生的是脚本运行,在$ i = 3之前没有任何内容打印到控制台,然后我一次打印3行:
My loop just executed
My loop just executed
My loop just executed
我无法理解为什么它不会在每次循环后打印而不是最后打印所有?
为什么会这样,我怎样才能让它像我期待的那样工作?任何帮助将不胜感激
答案 0 :(得分:7)
控制台输出已缓冲,没有人答应IO#flush
给你:
$i = 0
$num = 3
while $i < $num do
$stdout.puts "My loop just executed"
$stdout.flush
sleep 10
$i +=1
end
答案 1 :(得分:6)
如果stdout是终端设备(tty),Ruby会自动刷新输出,如果不是,则会缓冲输出。
例如,从终端运行此命令通常会立即输出“hello”:
$ ruby -e 'puts "hello" ; sleep 5 ; puts "world"'
hello
# 5 seconds delay
world
$
因为:
$ ruby -e 'puts $stdout.tty?'
true
而将输出管道输出到另一个命令通常会延迟(即缓冲)输出,直到脚本完成为止:
$ ruby -e 'puts "hello" ; sleep 5 ; puts "world"' | cat
# 5 seconds delay
hello
world
$
因为:
$ ruby -e 'puts $stdout.tty?' | cat
false
要立即刷新任何输出,无论stdout是否为tty,您都可以在脚本开头将$stdout
的{{3}}设置为true
:
$stdout.sync = true
应用于上面的例子:
$ ruby -e '$stdout.sync = true ; puts "hello" ; sleep 5 ; puts "world"' | cat
hello
# 5 seconds delay
world
$