来自$ stdout和$ stderr的Ruby同步输出

时间:2012-03-24 05:31:38

标签: ruby stdout stderr

我正在编写一个由各种子程序组成的程序,每个子程序都记录自己的错误。在执行结束时,我想将遇到的所有错误转储到由记录它们的程序标记的屏幕上。

理想情况下,我会这样:

Encountered 4 errors during compilation (STDOUT)
   Tokenizer Errors: (STDOUT)
      Line 4: Invalid symbol found '@' (STDERR)

   Parser Errors: (STDOUT)
      Line 7: expected 'end' but saw 'while' (STDERR)   
      Line 7: expected ';' but saw 'while'   (STDERR)
      Line 12 expected '.' but saw 'end'  (STDERR)

但是当我运行我的程序时,$ stdout行和$ stderr行正在混淆。我知道$ stdout缓冲区和$ stderr没有,所以我将这一行添加到打印输出的方法中:

$stdout.sync = $stderr.sync = true
我被告知的

应该同步两个输出流。但不幸的是,我仍然收到混乱的输出。我也尝试在我想发送到$ stdout的每一行之后添加$stdout.flush,但这似乎也没有效果。

以下是我正在使用的代码:

  def self.dump()
     $stdout.sync = $stderr.sync = true # attempted sync
     if not @@lexer_error_log.empty? or not @@parser_error_log.empty?
        puts "Encountered #{@@err_cnt} errors during compilation\n" 
        $stdout.flush #flush
     end

     if not @@lexer_error_log.empty?
       puts "\nTokenizer Errors:"
       $stdout.flush # flush
       @@lexer_error_log.each {|e| $stderr.puts "\t#{e}\n" }
     end 

     if not @@parser_error_log.empty?
       puts "Parser Errors:"
       $stdout.flush # flush
       @@parser_error_log.each {|e| $stderr.puts "\t#{e}\n" }
     end 
   end

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

一种可能的方法:将错误输出收集到String中,如下所示:

require 'stringio'

so = $stderr
$stderr = StringIO.new('', 'w')

# run your program

然后恢复$stderr或只打印字符串$stdout ...

puts $stderr.string