The problem

I was writing some tests around a Ruby library (day-job stuff) and needed some way to look at the debug output of the library. Since debug output is spewed to stdout and hacking up the library wasn't really feasible, I needed some way to get hold of stdout programmatically.

The solution

Temporarily redirect stdout into something the sort of looks like an output stream.

class StdOutCapturer
  attr_reader :output

  def initialize
    @output = ""
  end

  def write(s)
    @output += s
  end
end

def get_stdout(func, *params)
  orig_stdout = $stdout
  my_stdout = StdOutCapturer.new()
  $stdout = my_stdout
  result = func.call(*params)
  $stdout = orig_stdout
  return my_stdout.output, result
end

It is used like so:

txt, result = get_stdout(self.method("puts"), "foo")