SchmidtHappens

Don't Use system When Suppressing STDOUT

I recently needed to test the structure of a generated project and wanted to suppress STDOUT. Don't use system.

Okay, let me give you a little more detail. I just started playing around with using Thor to create a custom generator. One of the things I noticed immediately was that the output for the site creation was showing up every time a test called the generator. This is really annoying and I wanted to suppress the chatter.

After doing some searching around the internets, I discovered that I could temporarily change $stdout to use StringIO. Then, when I was done, switch it back to use the original $stdout. Here's the code for clarification:

def capture(stream)
  begin
    stream = stream.to_s
    eval "$#{stream} = StringIO.new"
    yield
    result = eval("$#{stream}").string
  ensure
    eval("$#{stream} = #{stream.upcase}")
  end

  result
end

After implementing this code, I was still getting output in my tests.

Screenshot of test run using the system command

It. Drove. Me. Nuts.

I did a little more research and discovered that the system method will invoke the command in a subshell. In order to capture $stdout properly, you will want to use either %x{cmd} or `cmd` formats.

Screenshot of test run using the system command

Something missing? Need more explanation? Let me know in the c-c-c-comments!

blog comments powered by Disqus