On Wed, May 07, 2003 at 07:53:05AM +0900, Simon Strandgaard wrote:
> I have seen much talking about this topic, but no working code!
> 
> I want to capture all output from [ruby, child_processes].
> How can I do this ?

> def capture
>     raise unless block_given?
>     a, b, c = $defout, $stderr, $stdout
>     buf = StringIO.new(s = "", "w")
>     begin
>         $defout, $stderr, $stdout = buf
You need to use $stdout.reopen(buf) here. Same for $stderr.

>         yield
>     ensure
>                 buf.close
>         $defout, $stderr, $stdout = a, b, c
>     end
>         s.split(/\n/)
> end
> 
> res = capture {
>         puts "1"
>         system("ruby output.rb")  # BOOM - Output is not being captured?
>         puts "2"
> }
> puts res.collect{|s| "OK "+s }.join("\n")
> > cat output.rb
> $stderr.puts "stderr"
> $stdout.puts "stdout"
> $defout.puts "defout"

But since IO::reopen seems to be a quite special function (it actually
_replaces_ its receiver - it's the only ruby function I know of that does
this), it might be that the argument has to be of a special class (maybe
derived from IO?).

I also never used stringio, so I can't tell wheather it's "compatible
enough" with IO to use it as a parameter to reopen().

Maybe someone with more knowledge of those ruby internals can clarify these
issues.

greetings, Florian Pflug