# Capturing standard out?

**URL:** <https://www.ruby-forum.com/t/capturing-standard-out/89369>\
**Category:** Ruby\
**Created:** [March 19, 2007, 11:19pm UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369 "2007-03-19T23:19:09Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 19, 2007, 11:19pm UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/1 "2007-03-19T23:19:09Z")

</div>

Is there an easy way to capture standard out in Ruby, so that “puts”  
throws its output into a buffer instead of just popping up on the  
screen?

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 19, 2007, 11:44pm UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/2 "2007-03-19T23:44:14Z")

</div>

On 3/19/07, Giles B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

I have a scriopt producing output for bash, for running the test spec  
I plugin output into an array, more or less like this:

class Output  
@data =[]  
class \<\< self  
attr\_reader :data  
end  
end  
if $TESTING then  
def Kernl.puts \*args, &blk  
Output.data \<\< args.join(“”)  
Output.data \<\< blk.call if blk  
end  
end

I have also Output.data.clear in #setup of the testsuite.

HTH  
Robert

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 19, 2007, 11:53pm UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/3 "2007-03-19T23:53:16Z")

</div>

On Mar 19, 2007, at 6:18 PM, Giles B. wrote:

> Is there an easy way to capture standard out in Ruby, so that “puts”  
> throws its output into a buffer instead of just popping up on the  
> screen?

This is exactly the problem shell IO redirection was designed to solve.

$ ruby script.rb \> output

What is the use case that prevents you from using shell redirection?

Gary W.

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 20, 2007, 12:52am UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/4 "2007-03-20T00:52:28Z")

</div>

On 3/19/07, Daniel S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Tue, 2007-03-20 at 07:18 +0900, Giles B. wrote:
> 
> > Is there an easy way to capture standard out in Ruby, so that “puts”  
> > throws its output into a buffer instead of just popping up on the  
> > screen?
> 
> You can set the $stdout global variable to point to whatever object you  
> like, as long as it adheres to a simple interface. Kernel#puts simply  
> redirects to $stdout.  
> That is a good idea too, especially with this idiom

def xxx(…, out = $stdout)

Robert

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 20, 2007, 12:09am UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/5 "2007-03-20T00:09:17Z")

</div>

On Tue, 2007-03-20 at 07:18 +0900, Giles B. wrote:

> Is there an easy way to capture standard out in Ruby, so that “puts”  
> throws its output into a buffer instead of just popping up on the  
> screen?

You can set the $stdout global variable to point to whatever object you  
like, as long as it adheres to a simple interface. Kernel#puts simply  
redirects to $stdout.

Cheers,  
Daniel

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 20, 2007, 1:49am UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/6 "2007-03-20T01:49:32Z")

</div>

On 3/19/07, Daniel S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Cheers,  
> Daniel

Hey Daniel, I found an example of the $stdout technique from Matz:

[http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/15519](http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/15519)

That’s what I ended up using, although I used $stdout and instead of  
$defout, and the documentation I found said assigning to $stdout is  
deprecated in favor of $stdout.reopen, which I couldn’t seem to get to  
work for me.

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 20, 2007, 7:06pm UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/7 "2007-03-20T19:06:21Z")

</div>

Here’s a code snippet from my log library.

gegroet,  
Erik V. - [http://www.erikveen.dds.nl/](http://www.erikveen.dds.nl/)

* * *

[“$stdout”, “$stderr”].each do |std|  
io = eval(std)  
old\_write = io.method(:write)

class \<\< io  
self  
end.module\_eval do  
define\_method(:write) do |text|  
unless text =~ /^[\r\n]+$/ # Because puts calls twice.  
File.open(“logfile.log”, “a”) do |f|  
f.puts [std[1…-1].upcase, caller[2], text].join(" ")  
end  
end

```
   old_write.call(text)
 end

```

end  
end

$stdout.puts “text on stdout”  
$stderr.puts “text on stderr”

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 20, 2007, 1:53am UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/8 "2007-03-20T01:53:32Z")

</div>

On 3/19/07, Gary W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> What is the use case that prevents you from using shell redirection?

I have no idea, I’m solving this for somebody I work with, but I’m  
pretty confident they’re familiar with shell redirection already.  
Thanks tho.

---

<div class="post-metadata">

**Author:** ![Giles\_B](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/848f3c/32.png) [@Giles\_B](https://www.ruby-forum.com/u/Giles_B)\
**Post date:** [March 26, 2007, 5:54pm UTC](https://www.ruby-forum.com/t/capturing-standard-out/89369/9 "2007-03-26T17:54:41Z")

</div>

On Mar 19, 2007, at 5:18 PM, Giles B. wrote:

> Is there an easy way to capture standard out in Ruby, so that “puts”  
> throws its output into a buffer instead of just popping up on the  
> screen?

I would do it like this:

#!/usr/bin/env ruby -w

require “stringio”

def capture\_stdout(buffer = StringIO.new)  
saved\_stdout = $stdout  
$stdout = buffer

yield

$stdout = saved\_stdout

buffer.string rescue buffer  
end

if **FILE** == $PROGRAM\_NAME  
puts “This will be printed.”  
output = capture\_stdout { puts “Meanwhile, this was captured.” }  
puts “This also will be printed.”  
p output  
end

**END**

James Edward G. II
