web-dev-qa-db-ja.com

stdoutをすぐに印刷する方法は?

stdoutをすぐに出力するにはどうすればよいですか? stdoutは、すべての入力が完了した後に印刷されます。

require 'open3'
def run(cmd)
    Open3.popen3(cmd) do |stdin, stdout, stderr, thread|

    Thread.new do
      stdout.each {|l| puts l}
    end

    Thread.new do
      while thread.alive?
        stdin.puts $stdin.gets
      end
    end

    thread.join
  end
end

run ("Ruby file_to_test.rb")

file_to_test.rb:

puts "please, enter s"
puts "please, enter q"

s = gets.chomp!
q = gets.chomp!

puts s
puts q

Main.rbを実行した後の結果は次のとおりです。

somestring
somestring2
please, enter s
please, enter q
somestring
somestring2

stdoutをすぐに出力するにはどうすればよいですか?

15
xitryuga

Rubyは出力バッファがいっぱいになるまで出力をバッファリングしています。自動的に書き込むように動作を変更するには、 sync および sync= を使用します。

old_sync = $stdout.sync
$stdout.sync = true

puts "immediately output lotsa stuff"
puts "immediately output lotsa stuff"
puts "immediately output lotsa stuff"
puts "immediately output lotsa stuff"

# reenable the default behavior
$stdout.sync = old_sync

sync=のドキュメントから:

「同期モード」をtrueまたはfalseに設定します。同期モードがtrueの場合、すべての出力はすぐに基盤となるオペレーティングシステムにフラッシュされ、内部でバッファリングされません。

バッファの自動フラッシュを有効にすると、コードの全体的な実行速度が実際に遅くなる可能性があることを理解することが重要です。特に、データをチャンクで受け取りたいファイルやデバイスに書き込んでいる場合はそうです。 syncを使用するか、慎重にフラッシュしてください。

13
the Tin Man

出力をフラッシュする

探しているのは、flushメソッドを使用してioストリームをフラッシュすることです。

各イテレーションまたは各プットの後に次のことを試してください。

stdout.flush

複数のプットが連続していた場合は、最後のフラッシュの後にフラッシュを実行することをお勧めします。そうすれば、頻繁に実行しないでください。例:

stdout.puts "Hello"
stdout.puts "Mate"
stdout.flush
4
roychri