Forum: Ruby capturing standard out?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ce8b03e5750097942c58e12b46724312?d=identicon&s=25 Giles Bowkett (Guest)
on 2007-03-19 23:19
(Received via mailing list)
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?
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-03-19 23:44
(Received via mailing list)
On 3/19/07, Giles Bowkett <gilesb@gmail.com> 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
E7559e558ececa67c40f452483b9ac8c?d=identicon&s=25 Gary Wright (Guest)
on 2007-03-19 23:53
(Received via mailing list)
On Mar 19, 2007, at 6:18 PM, Giles Bowkett 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 Wright
5da4c52f43677f395aff5bde775593c2?d=identicon&s=25 Daniel Schierbeck (dasch)
on 2007-03-20 00:09
(Received via mailing list)
On Tue, 2007-03-20 at 07:18 +0900, Giles Bowkett 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
703fbc991fd63e0e1db54dca9ea31b53?d=identicon&s=25 Robert Dober (Guest)
on 2007-03-20 00:52
(Received via mailing list)
On 3/19/07, Daniel Schierbeck <daniel.schierbeck@gmail.com> wrote:
> On Tue, 2007-03-20 at 07:18 +0900, Giles Bowkett 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
Ce8b03e5750097942c58e12b46724312?d=identicon&s=25 Giles Bowkett (Guest)
on 2007-03-20 01:49
(Received via mailing list)
On 3/19/07, Daniel Schierbeck <daniel.schierbeck@gmail.com> 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/...

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.
Ce8b03e5750097942c58e12b46724312?d=identicon&s=25 Giles Bowkett (Guest)
on 2007-03-20 01:53
(Received via mailing list)
On 3/19/07, Gary Wright <gwtmp01@mac.com> 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.
6b0967f63d03e99b6c07a3f5ed224c77?d=identicon&s=25 Erik Veenstra (Guest)
on 2007-03-20 19:06
(Received via mailing list)
Here's a code snippet from my log library.

gegroet,
Erik V. - 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"
4299e35bacef054df40583da2d51edea?d=identicon&s=25 James Gray (bbazzarrakk)
on 2007-03-26 17:54
(Received via mailing list)
On Mar 19, 2007, at 5:18 PM, Giles Bowkett 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 Gray II
This topic is locked and can not be replied to.