From: Jean-Claude Arbaut Date: 2005-10-25T07:22:02+09:00 Subject: Re: $stderr.reopen bug? Tanner Burson wrote: > > I tried this approach first, and it didn't seem to accomplish anything (IRB > dump below) > > irb(main):007:0> require 'stringio' > => false > irb(main):008:0> str_io = StringIO.new("") > => # > irb(main):009:0> $stderr = str_io > => # > irb(main):010:0> `asdf` #bad command, dumps to stderr > (irb):10: command not found: asdf > => "" > irb(main):011:0> $stderr.rewind > => 0 > irb(main):012:0> puts $stderr.read > > => nil > irb(main):013:0> > > as compared to the version reopening as file: > > irb(main):001:0> require 'stringio' > => true > irb(main):002:0> $stderr.reopen('/dev/null','w+') > => # > irb(main):003:0> `asdf` #bad command again > => "" > > any idea why there is such a difference between the two? I have not a complete answer (I'd need to look a irb source), but an hint: irb(main):001:0> warn 'bouh' bouh => nil irb(main):002:0> `bouh` (irb):2: command not found: bouh => "" The two messages are not formated the same way, so I suspect they are not sent to the same "stderr". Actually, the line "command not found: bouh" is the answer from the shell, and the warning is processed inside Ruby. Maybe $stderr assignment is only valid for ruby output. If I'm not wrong: * if you reopen $stderr, you manipulate the original *file* in /dev/stderr, therefore the shell will send its error to the same file as Ruby * but if you assign $stderr, the file /dev/stderr doesn't change, only the "file" Ruby errors are sent to does. I'm not completely sure it works that way, though...