# Event-based stdout content capturing

**URL:** <https://www.ruby-forum.com/t/event-based-stdout-content-capturing/159313>\
**Category:** Ruby\
**Created:** [February 3, 2009, 12:20pm UTC](https://www.ruby-forum.com/t/event-based-stdout-content-capturing/159313 "2009-02-03T12:20:45Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![daniel304](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e5b9ba/32.png) [@daniel304](https://www.ruby-forum.com/u/daniel304)\
**Post date:** [February 3, 2009, 12:20pm UTC](https://www.ruby-forum.com/t/event-based-stdout-content-capturing/159313/1 "2009-02-03T12:20:45Z")

</div>

Some legacy code produces output to STDOUT during execution. I need to  
capture it on even-based model, something like the following:

capture the\_legacy\_code\_lambda do |content|

# do something with content each time something appears in STDOUT

end

how can I manage this? Are there any idioms?

---

<div class="post-metadata">

**Author:** ![daniel304](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e5b9ba/32.png) [@daniel304](https://www.ruby-forum.com/u/daniel304)\
**Post date:** [February 4, 2009, 2:24am UTC](https://www.ruby-forum.com/t/event-based-stdout-content-capturing/159313/2 "2009-02-04T02:24:34Z")

</div>

On Tue, Feb 3, 2009 at 11:19 AM, Daniel V.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Some legacy code produces output to STDOUT during execution. I need to  
> capture it on even-based model, something like the following:
> 
> capture the\_legacy\_code\_lambda do |content|
> 
> # do something with content each time something appears in STDOUT
> 
> end
> 
> how can I manage this? Are there any idioms?

You can reassign to the global $stdout object any object which  
provides the method #write. You could use that to capture the output  
something like this:

class Capture  
def initialize(\*args, &block)  
@block = block  
end  
def write(txt)  
@block.call(txt)  
end  
end

def capture(code, &block)  
old\_stdout = $stdout  
begin  
$stdout = Capture.new(&block)  
code.call  
ensure  
$stdout = old\_stdout  
end  
end

def legacy\_code  
puts “hello world”  
puts “me again”  
raise Exception, “Oh no!”  
end

puts “start”  
begin  
capture(proc { legacy\_code }) do |txt|  
STDOUT.print “captured [”  
STDOUT.print txt  
STDOUT.puts “]”  
STDOUT.flush  
end  
rescue Object =\> e  
puts “Got exception”  
raise  
end  
puts “end”

# $ ruby capture-stdout.rb

# start

# captured [hello world]

# captured [

# ]

# captured [me again]

# captured [

# ]

# Got exception

# capture-stdout.rb:23:in `legacy\_code’: Oh no! (Exception)

# etc.

Regards,  
Sean

---

<div class="post-metadata">

**Author:** ![daniel304](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/e5b9ba/32.png) [@daniel304](https://www.ruby-forum.com/u/daniel304)\
**Post date:** [February 4, 2009, 6:25am UTC](https://www.ruby-forum.com/t/event-based-stdout-content-capturing/159313/3 "2009-02-04T06:25:34Z")

</div>

Thank you very much, great idea! I missed in my mind, that puts just  
uses global variable $stdout.
