Redirecting stderr in irb

Redirecting $stderr in irb doesn’t work but redirecting
$DEFAULT_OUTPUT does. Can anyone explain why this happens? Also, is
there any clever way to run irb in a thread and then redirect
$DEFAULT_OUTPUT only for that thread?

$ irb
irb(main):001:0> require ‘stringio’
=> true
irb(main):002:0> $stderr = StringIO.new
=> #StringIO:0x9b87698
irb(main):003:0> hello
NameError: undefined local variable or method hello' for main:Object from (irb):3 from /usr/bin/irb:12:in
irb(main):004:0> $> = StringIO.new
irb(main):005:0> hello
irb(main):006:0>

(Sorry if you’re seeing this twice, didn’t get any response in
ruby-core so I’m forwarding to ruby-talk)

martin

On Dec 21, 2009, at 00:26 , Martin DeMello wrote:

Redirecting $stderr in irb doesn’t work but redirecting
$DEFAULT_OUTPUT does.

“doesn’t work” is hardly true. You’re certainly redirecting $stderr at
the time. What you’re confusing is that $DEFAULT_OUTPUT is not an alias
for $stderr, but for $stdout. This is easily testable just by playing
with the shell:

% irb --noreadline 2> x

blah
NameError: undefined local variable or method `blah’ for main:Object
from (irb):1

^d
% cat x
%

Unfortunately, irb decided to print via STDOUT (which I prefer to keep
hands off and play with $stdout only), so messing with it (for me) is a
no-no.

class StdioOutputMethod<OutputMethod
def print(*opts)
STDOUT.print(*opts)
end
end

I think what you really want to do is to temporarily reassign
output_method in the context.

On Mon, Dec 21, 2009 at 3:39 PM, Ryan D. [email protected]
wrote:

On Dec 21, 2009, at 00:26 , Martin DeMello wrote:

Redirecting $stderr in irb doesn’t work but redirecting
$DEFAULT_OUTPUT does.

“doesn’t work” is hardly true. You’re certainly redirecting $stderr at the time. What you’re confusing is that $DEFAULT_OUTPUT is not an alias for $stderr, but for $stdout. This is easily testable just by playing with the shell:

Yeah, i know that, but irb seems to be printing its errors to
$DEFAULT_OUTPUT

I think what you really want to do is to temporarily reassign output_method in the context.

Well, irb.rb has

def output_value
if @context.inspect?
printf @context.return_format, @context.last_value.inspect
else
printf @context.return_format, @context.last_value
end
end

So, if I redefine output_method I also need to reopen Irb to override
output_value and have it call @context.output_method.printf rather
than printf. Anyway I did that, and regular output gets redirected
appropriately, but errors don’t. It looks like it’s hardcoding
StdioOutputMethod somewhere, but I couldn’t figure out how to override
that.

martin