Ruby синхронизировал вывод из $ stdout и $ stderr - PullRequest
0 голосов
/ 24 марта 2012

Я пишу программу, которая состоит из различных подпрограмм, каждая из которых регистрирует свои ошибки.В конце выполнения я хотел бы сбросить все ошибки, которые были обнаружены, на экран, помеченный программой, которая их зарегистрировала.

В идеале у меня было бы что-то вроде этого:

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.flush после каждой строки, которую я хотел отправить в $ stdout, но это также, похоже, не дает никакого эффекта.

Вот код, который я использую:

  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 Ответ

1 голос
/ 24 марта 2012

Один из возможных подходов: собрать вывод ошибок в String примерно так:

require 'stringio'

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

# run your program

А затем либо восстановите $stderr, либо просто напечатайте строку в $stdout ...

puts $stderr.string
...