[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to extend $stdout#write for system calls?

Jim Freeze

2/24/2005 10:06:00 PM

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


9 Answers

Joel VanderWerf

2/24/2005 10:19:00 PM

0

Jim Freeze wrote:
> 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.

How could this work if echo is not even a ruby program? Maybe if you run
echo with popen, and print the output of that... But if you want it to
work with arb. ruby code, this won't help.

Probably the only hope is to $stdout.reopen into something you can read
and do what you want with. Never tried it tho.


Jim Freeze

2/24/2005 10:44:00 PM

0

* Joel VanderWerf <vjoel@PATH.Berkeley.EDU> [2005-02-25 07:19:12 +0900]:

> How could this work if echo is not even a ruby program? Maybe if you run
> echo with popen, and print the output of that... But if you want it to
> work with arb. ruby code, this won't help.

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:

IO::Tee(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


Joel VanderWerf

2/24/2005 11:23:00 PM

0

Jim Freeze wrote:
> * Joel VanderWerf <vjoel@PATH.Berkeley.EDU> [2005-02-25 07:19:12 +0900]:
>
>
>>How could this work if echo is not even a ruby program? Maybe if you run
>>echo with popen, and print the output of that... But if you want it to
>>work with arb. ruby code, this won't help.
>
>
> 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).

A child process inherits the file handle that $stdout refers to, but not
the ruby object itself, even if the child process is ruby.

> The idea is to do the following:
>
> IO::Tee(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.

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.


Joel VanderWerf

2/24/2005 11:27:00 PM

0

Joel VanderWerf wrote:
> 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"
system("echo", "from system")
end


Head.whack! I forgot to show that this does work with system calls...


djberg96

2/25/2005 5:18:00 AM

0

Jim Freeze wrote:
> Hi
>
> I am writing a tee function for ruby and am pretty close.

Does Sean Chittenden's io-tee package not work? It's on the RAA.

Regards,

Dan

Jim Freeze

2/25/2005 5:22:00 AM

0

* Daniel Berger <djberg96@hotmail.com> [2005-02-25 14:20:00 +0900]:

> Does Sean Chittenden's io-tee package not work? It's on the RAA.

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 Freeze

2/25/2005 5:25:00 AM

0

* Joel VanderWerf <vjoel@PATH.Berkeley.EDU> [2005-02-25 08:27:04 +0900]:

> Joel VanderWerf wrote:
> >class IO
> > def tee
> > IO.popen("-") do |pipe| # Won't work on mswin.

Windows shmwindows. So what? ;)

> > 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"
> system("echo", "from system")
> end

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


djberg96

2/25/2005 7:37:00 PM

0


Jim Freeze wrote:
> * Daniel Berger <djberg96@hotmail.com> [2005-02-25 14:20:00 +0900]:
>
> > Does Sean Chittenden's io-tee package not work? It's on the RAA.
>
> 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

Ah, you're right. In any case, if you can read Perl it's probably
worth your while to look at Chung-chieh Shan's IO::Tee module, on CPAN.

Regards,

Dan

Jim Freeze

2/25/2005 7:53:00 PM

0

* Daniel Berger <djberg96@hotmail.com> [2005-02-26 04:39:58 +0900]:

> Ah, you're right. In any case, if you can read Perl it's probably
> worth your while to look at Chung-chieh Shan's IO::Tee module, on CPAN.

Thanks. I'll take a look


--
Jim Freeze
Code Red. Code Ruby