@jim: "Hi
I am writing a tee function for ruby and am pretty close.
The problem I am having now is that I don't know
how to extend $stdout#write and have it survive
a system (or exec) call.
Below is some code illustrating what I have:
 > cat tee.rb
 module M
   def write(a)
     super("fred\n")
   end
 end
 $stdout.extend(M)
 puts "puts: should be fred" # prints twice for some reason
 system("echo", "system: should be fred") # no fred
 > ruby tee.rb
 fred
 fred
 system: should be fred
If this is not possible, maybe there is a way with alias_method,
but I haven't been able to get that going either.
TIA
Jim Freeze
Code Red. Code Ruby"
    @jim: "* Joel VanderWerf <email_address> [2005-02-25 07:19:12 +0900]:
<quote>
It may not be possible. My knowledge of $stdout doesn't run too deep.
So far, I have wrapped the write call, so puts is captured and I 
have reopened stdout to write to a file. So, I figured there should
be a way to capture a system call (since it inherits $stdout from the
current process).
The idea is to do the following:
IO888a:dbb7:2d49:b3f6:8605:bf4e:caed:e5a4Tee(file) { 
  # all output is to go to file and screen
  puts "from ruby puts"
  system("echo", "from system")
  exec("echo", "from system")
}
and have the contents of file and the screen be identical.
Jim Freeze
Code Red. Code Ruby"
    @vjoel: "<quote>
A child process inherits the file handle that $stdout refers to, but not 
the ruby object itself, even if the child process is ruby.
You'll be disappointed by the following if you are using windows, but 
what else is new.
class IO
   def tee
     IO.popen("-") do |pipe| # Won't work on mswin.
       if pipe # parent
         while (str = pipe.gets)
           puts str
           $stdout.puts str
         end
       else # child
         yield
       end
     end
   end
end
f=File.open("/tmp/tee-example-output", "w+")
f.tee do
   puts "something"
   puts "something else"
end
f.rewind
puts "The contents of file is:\n#{f.read.inspect}"
-
output:
something
something else
The contents of file is:
"something\nsomething else\n"
Note that the "tee" block is executed in a child process, so state (e.g. 
local vars) will not be changed when you get back to the main process."
    @vjoel: "<quote>
f.tee do
   puts "something"
   puts "something else"
   system("echo", "from system")
end
Head.whack! I forgot to show that this does work with system calls..."
    @jim: "* Daniel Berger <email_address> [2005-02-25 14:20:00 +0900]:
<quote>
Don't know. rubynet.org seems to be down. I wrote Sean about
it this morning, but no reply.
Jim Freeze
Code Red. Code Ruby"
    @jim: "* Joel VanderWerf <email_address> [2005-02-25 08:27:04 +0900]:
<quote>
Windows shmwindows. So what?  ;)
Nice twist on this. I like it, but maybe I'm too tired.
How would I integrate capturing stderr also?
I tried popen3, but couldn't get that to work either.
Jim Freeze
Code Red. Code Ruby"
    @jim: "* Daniel Berger <email_address> [2005-02-26 04:39:58 +0900]:
<quote>
Thanks. I'll take a look
Jim Freeze
Code Red. Code Ruby"
{'source': 'USENET', 'other_information': '{"reply_count": 6, "forum_name": "comp.lang.ruby.20141021.mbox"}', 'file': 'data/output/usenet-comp.lang.parquet'}