On Tue, 10 Feb 2004 12:14:39 +0100, Simon Strandgaard wrote:

> I want to temporarily capture stderr output.
> Im on a freebsd box, so pipe should work.
> 
> What am I doing wrong?

Forgot to do thread.join ... Now it works.

BTW: Is there a platform independent way to capture
$stderr output ?

--
Simon Strandgaard


server> ruby x.rb
Loaded suite TestCapture
Started
..
Finished in 0.004465 seconds.

1 tests, 1 assertions, 0 failures, 0 errors
server> cat x.rb 
require 'test/unit'

class TestCapture < Test::Unit::TestCase
  def capture_stderr(&block)
    reader, writer = IO.pipe
    result = ""
    thread = Thread.new do
      fds = [reader]
      loop do
        res = select(fds, nil, nil, nil)[0]
        if res.include?(reader)
          if reader.eof
            thread.kill
          else
            result += reader.read
          end
        end
      end
    end
    old_stderr = $stderr.dup
    $stderr.reopen(writer)
    block.call
    $stderr.flush
    writer.close
    $stderr.reopen(old_stderr)
    thread.join
    reader.close
    return result
  end
  def test_capture_stderr
    str = capture_stderr {
      $stderr.puts("hello world")
    }
    assert_equal("hello world\n", str)
  end
end

if $0 == __FILE__
  require 'test/unit/ui/console/testrunner'
  Test::Unit::UI::Console::TestRunner.run(TestCapture)
end
server>