Ruby while while while while while

Bra*_*rad 1 ruby sleep loops

鉴于以下红宝石:

$i = 0
$num = 3

while $i < $num  do
    puts "My loop just executed"
    sleep 10
    $i +=1
end
Run Code Online (Sandbox Code Playgroud)

我希望每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
Run Code Online (Sandbox Code Playgroud)

然而,实际发生的是脚本运行,在$ i = 3之前没有任何内容打印到控制台,然后我立刻打印3行:

My loop just executed
My loop just executed
My loop just executed
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它不会在每个循环后打印而不是打印到最后?

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

Ale*_*kin 7

控制台输出是缓冲的,没人答应给IO#flush你:

$i = 0
$num = 3

while $i < $num  do
    $stdout.puts "My loop just executed"
    $stdout.flush
    sleep 10
    $i +=1
end
Run Code Online (Sandbox Code Playgroud)


Ste*_*fan 6

如果stdout是终端设备(tty),Ruby会自动刷新输出,如果不是,则缓冲输出.

例如,从终端运行此命令通常会立即输出"hello":

$ ruby -e 'puts "hello" ; sleep 5 ; puts "world"'
hello
# 5 seconds delay
world
$
Run Code Online (Sandbox Code Playgroud)

因为:

$ ruby -e 'puts $stdout.tty?'
true
Run Code Online (Sandbox Code Playgroud)

而输出到另一个命令通常会延迟(即缓冲)输出,直到脚本完成为止:

$ ruby -e 'puts "hello" ; sleep 5 ; puts "world"' | cat
# 5 seconds delay
hello
world
$
Run Code Online (Sandbox Code Playgroud)

因为:

$ ruby -e 'puts $stdout.tty?' | cat
false
Run Code Online (Sandbox Code Playgroud)

要立即刷新任何输出,无论标准输出是一个TTY,您可以设置$stdoutS" synctrue你的脚本的开头:

$stdout.sync = true
Run Code Online (Sandbox Code Playgroud)

适用于上面的例子:

$ ruby -e '$stdout.sync = true ; puts "hello" ; sleep 5 ; puts "world"' | cat
hello
# 5 seconds delay
world
$
Run Code Online (Sandbox Code Playgroud)