From: Eric Hodel Date: 2009-05-21T04:01:25+09:00 Subject: Re: I want to redirect stderr to StringIO. On May 19, 2009, at 23:14, Robert Klemme wrote: > 2009/5/20 Eric Hodel : >> On May 19, 2009, at 21:30, ErMaker wrote: >> >>>>> IO.new(2).reopen(StringIO.new) >>> >>> TypeError: can't convert StringIO into String >>> from (irb):1:in `reopen' >>> from (irb):1 >>>>> >>>>> IO.new(2).reopen(IO.new(1)) >>> >>> => # >>> >>> StringIO also do as IO, but IO#reopen fails. >>> >>> I want to redirect stderr to StringIO, but it doesn't work. >> >> Always use reopen as a last resort. >> >> http://blog.segment7.net/articles/2006/08/17/stdout-vs-stdout > > I am not sure I agree. Actually, if you want the redirection to be > permanent for sub processes you have to use $stdout.reopen. And this > is not a "last resort" but the proper solution. Most of the time people capture IO from sub processes via Kernel#` or IO::popen instead of handling the sub process themselves. Ruby's nice features make use of #reopen an exceptional circumstance, but there are times where it's appropriate. > Btw, in 1.8 there is also $defout - I believe _that- is the stream > used by Kernel#puts and the like in those versions: > > 08:13:00 ~$ ruby -r stringio -e 'puts 1; $defout=StringIO.new; puts 2' > 1 > -e:1: warning: $defout is obsolete; use $stdout instead This warning says otherwise. They happen to be the same object though: $ ruby -e 'p $stdout.object_id, $defout.object_id' 97260 97260