Trying to be a little fancy but can’t figure out how to do it right.
Basically I want to redirect STDOUT and STDERR so that they each
continue to write to their default streams but also write to a log file.
The goal is that ALL of the rest of the code can be completely oblivious
and continue to write to STDOUT and STDERR as normal and the Tee-ing
will work automatically.
I tried the following simple experiment:
class Tee < IO def initialize (*fhs) @fhs = fhs end def write (string) @fhs.each do |fh| fh.print string end end end $stdout = Tee.new($stdout) puts "Hello world" system("pwd")
I get the following:
Hello world bar.rb:21:in `system': uninitialized stream (IOError)
from bar.rb:21:in `’
So the native Ruby I/O seems to work but somehow the system command does
not like this. I suspect what’s going on is that the native Ruby I/O
commands have logic to handle a true stream and a virtual stream like
this differently, whereas the system command does not. Yes, I know that
I could rewrite the system call to capture the output explicitly and use
print to write it out but, again, the point of this experiment is to
capture any and I/O and be agnostic of how the code is written. I could
use pipes and such but I’m sure there must be a more elegant way to do
Any help is appreciated.