为什么$ stdout没有工作?

时间:2013-09-12 15:36:41

标签: ruby file-io stdout

我似乎无法使文件输出正常工作:

record = File.open("/tmp/record", "w")

old_stdout = $stdout
$stdout = record
$stderr = $stdout

puts "This is a record"
z = 10/0

当我从命令行或pry运行它时,我似乎无法将输出转换为文件。任何想法为什么这不起作用?

1 个答案:

答案 0 :(得分:0)

一个可能的问题是您没有关闭文件流。

这样做很重要,因为文件缓冲区可能没有刷新到文件本身。因为您的代码使用零分区生成错误,所以Ruby可能也没有正确关闭文件。

也就是说,您的代码可以写得更干净,更像Ruby,而不会破坏puts如何用于写入文件:

File.open("/tmp/record", "w") do |record|
  record.puts "This is a record"
end

当块退出时,它会自动关闭文件输出。

也许您正在尝试捕获使用z = 10/0生成的自引入零分割异常的输出?

你可以通过拯救例外来做到这一点;如果没有这个,你就无法让Ruby继续运行:

File.open("./record", "w") do |record|

  record.puts "This is a record"

  begin
    z = 10/0
  rescue Exception => e
    record.puts e.message
  end

end

跑完后,“记录”包含:

This is a record
divided by 0

或者,你可以这样做:

File.open("./record", "w") do |record|

  old_stdout, old_stderr = $stdout, $old_stderr
  $stdout = $stderr = record

  puts "This is a record"

  begin
    z = 10/0
  rescue Exception => e
    puts e.message
  end

  $stdout, $stderr = old_stdout, old_stderr
end

在运行之后,“记录”再次包含:

This is a record
divided by 0

有时我们想通过重新分配STDOUT和STDERR来玩游戏,但是,一般来说,我建议不要这样做。相反,使用以下内容直接写入:

$sterr.puts "foo blowed up"

这是为了使可读性和可维护性更加明显。如果你已经将$ stderr重定向到一个文件,并且它是凌晨3点,而你正在尝试记住代码的作用,因为你有一个系统关闭,并且你没有看到你想要的输出,你可能会想要重写代码是上面的代码,或者强迫某些东西强制输出你期望的东西。混乱可以从那里级联。