I want to temporarily capture stderr output.
Im on a freebsd box, so pipe should work.
What am I doing wrong?
···
–
Simon Strandgaard
ruby x.rb
Loaded suite TestCapture
Started
F
Finished in 0.023457 seconds.
Failure:
test_capture_stderr(TestCapture) [x.rb:31]:
<“hello world”> expected but was
<“”>.
1 tests, 1 assertions, 1 failures, 0 errors
cat x.rb
require ‘test/unit’
class TestCapture < Test::Unit::TestCase
def capture_stderr(&block)
reader, writer = IO.pipe
result = “”
thread = Thread.new do
loop do
res = select([reader], nil, nil, nil)[0]
if res.include?(reader)
unless reader.eof
result += reader.read
end
end
end
end
old_stderr = $stderr.dup
$stderr.reopen(writer)
block.call
$stderr.flush
$stderr.reopen(old_stderr)
thread.kill
writer.close
reader.close
return result
end
def test_capture_stderr
str = capture_stderr {
$stderr.puts(“hello world”)
}
assert_equal(“hello world”, str)
end
end
if $0 == FILE
require ‘test/unit/ui/console/testrunner’
Test::Unit::UI::Console::TestRunner.run(TestCapture)
end
BTW: Is there a platform independent way to capture
$stderr output ?
···
On Tue, 10 Feb 2004 12:14:39 +0100, Simon Strandgaard wrote:
I want to temporarily capture stderr output.
Im on a freebsd box, so pipe should work.
What am I doing wrong?
–
Simon Strandgaard
ruby x.rb
Loaded suite TestCapture
Started
…
Finished in 0.004465 seconds.
1 tests, 1 assertions, 0 failures, 0 errors
cat x.rb
require ‘test/unit’
class TestCapture < Test::Unit::TestCase
def capture_stderr(&block)
reader, writer = IO.pipe
result = “”
thread = Thread.new do
fds = [reader]
loop do
res = select(fds, nil, nil, nil)[0]
if res.include?(reader)
if reader.eof
thread.kill
else
result += reader.read
end
end
end
end
old_stderr = $stderr.dup
$stderr.reopen(writer)
block.call
$stderr.flush
writer.close
$stderr.reopen(old_stderr)
thread.join
reader.close
return result
end
def test_capture_stderr
str = capture_stderr {
$stderr.puts(“hello world”)
}
assert_equal(“hello world\n”, str)
end
end
if $0 == FILE
require ‘test/unit/ui/console/testrunner’
Test::Unit::UI::Console::TestRunner.run(TestCapture)
end
Date: Tue, 10 Feb 2004 12:14:39 +0100
From: Simon Strandgaard neoneye@adslhome.dk
Newsgroups: comp.lang.ruby
Subject: capture stderr
I want to temporarily capture stderr output. Im on a freebsd box, so pipe
should work.
a pipe should work - but it’s pretty tricky…
What am I doing wrong?
IO#read blocks until eof is read - your loop will only happen once and tries
to read all data at once. if you really wanted to do something like that
you’d need to do something like
require ‘io/nonblock’ # i love this module
buf = ‘’
loop do
select [r], nil, nil
buf << r.nonblock{ r.read }
end
your ‘read’ blocks:
~/eg/ruby > cat a.rb
r, w = IO.pipe
t = Thread.new do
puts ‘selecting…’
select [r], nil, nil
p r.read
end
w.puts 42
t.join
puts ‘never reached’
~/eg/ruby > ruby a.rb
selecting…
(hangs forever)
in the end, i think you can accomplish this much more easily and portably:
The difference between art and science is that science is what we
understand well enough to explain to a computer.
Art is everything else.
– Donald Knuth, “Discover”
/bin/sh -c ‘for l in ruby perl;do $l -e “print "\x3a\x2d\x29\x0a"”;done’
===============================================================================
I want to temporarily capture stderr output. Im on a freebsd box, so pipe
should work.
a pipe should work - but it’s pretty tricky…
Yes I got the pipe working… didn’t you see my second mail?
What am I doing wrong?
IO#read blocks until eof is read - your loop will only happen once and tries
to read all data at once. if you really wanted to do something like that
you’d need to do something like
require ‘io/nonblock’ # i love this module
I have not yet tried using this module module… though I have experience
with non-blocking io.
[snip]
begin
$stderr = StringIO.new
yield
$stderr.rewind && $stderr.read
ensure
$stderr = STDERR
end
Thanks… I had forgotten the ‘ensure’ statement!
My code is now looking like:
def capture_stderr(&block)
e = StringIO.new
$stderr = e
block.call
return e.string
ensure
$stderr = STDERR
end
···
On Tue, 10 Feb 2004 08:17:06 -0700, Ara.T.Howard wrote: