So ruby has this libxml that writes validation errors directly to
standard
error. The only way I’ve been able to figure out how to capture this
output
and then use it programmatically (send to logger and/or display to the
user)
is to do something like this:
require ‘xml/libxml’
require ‘tempfile’
def capture_stderr()
begin
err_file = Tempfile.new(“err_file”)
err_file.close
old_stderr = STDERR.dup
STDERR.reopen(err_file.path)
STDERR.sync = true
result = yield
STDERR.flush
err_file.open
err_file.seek(0)
err_text = err_file.read
err_file.close
err_file.unlink
return result, err_text
ensure
STDERR.reopen(old_stderr)
end
end
And then I can call what I want to call like this:
result, errors = capture_stderr{ …do something with XML::Document and
XML::Dtd here… }
I’ve previously tried:
Altering $stderr variable or overriding the IO class to overrride the
puts
or write methods, or re-opening STDERR to a StringIO.
I figure none of these work because the STDERR call I want to intercept
is
actually in the C code that implements libxml as an fprintf
So no extent of ruby object space manipulation is going to change that.
Can anybody see any danger of breakage here? Or perhaps have some other
ideas on how to do this?