Ruby while while while while while

时间:2017-01-04 13:58:48

标签: ruby loops sleep

鉴于以下红宝石:

$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

我无法理解为什么它不会在每次循环后打印而不是最后打印所有?

为什么会这样,我怎样才能让它像我期待的那样工作?任何帮助将不胜感激

2 个答案:

答案 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
$