From: Markus Liebelt Date: 2004-07-17T02:47:15+09:00 Subject: Re: Fork style of little programs Hello Sean, your input gave me a solution that might be used in the future. >>>>> "Sean" == Sean O'Dell writes: Because I think other's may have the same issue as I had, I want to give a sketch of the solution. Sean> On Monday 12 July 2004 14:32, Markus Liebelt wrote: Sean> > My original question was a little bit misleading. I can restructure my programs, but I want to use them both directly in the shell as well as components in a bigger ruby program. >> I now try to combine the two little programs in one program without >> redefining the way their methods work. The first just writes out >> its result by "puts ...", the second uses the variable $stdin. But >> how could a new method look that combines the two? I have no idea >> how to write it down. Is there something to "fork" the first one, >> so that the second one can read from standard input while the first >> writes to standard output? Sean> IO.popen("-") do | pipe | Sean> if (pipe) then Sean> # in parent; communicate with child through pipe Sean> else Sean> # in child; communicate with parent through stdio Sean> end Sean> end I tried forth and back with your solution, but to no avail. But I read a lot in programming ruby (section IO), so I got a new idea. If I have a file tf.rb with definition of class TestFirst with method test_out, which normally writes on $stdout, and I have a second file ts.rb with definition of class TestSecond with method test_in, which normally reads from $stdin, the following will work: 1. change the second definition by providing an argument io 2. use it in the file usage of ts.rb (is there a name for that??): if __FILE__ == $0 puts TestSecond.new.test_in($stdin) end 3. Combine then the two programs in the following way: def test_both rd, wr = IO.pipe tmp_out = $stdout $> = wr TestFirst.new.test_out wr.close $> = tmp_out return TestSecond.new.test_in(rd) end 4. I'm sure there could be a way to abstract the surrounding away so that something like the following remains: use_read_writer( { TestFirst.new.test_out }, { | reader | TestSecond.new.test_in(reader) }) Anyone to help out ;-) The equivalent in the shell could look like this: $ ruby tf.rb | ruby ts.rb So the base idea is to open for each pipe in the usage in the shell a pipe in ruby, and redirect the $stdout to the writer of the pipe, give the IO object that is normally $stdin as argument to the method you want to call. I have tested this version with the cygwin shell under Win-XP and even in the DOS Shell (shudder) with ruby-1-8-1, it works (wow). I'm not sure that this is the simplest solution, but it is doable for me and I see no drawback of it. Sean> Sean O'Dell Many thank's to all the people that helped me and other rookies to get the right ideas. And thank' to the creator of ruby to that wonderful language (never thought that I will find something more consistent and elegant than Smalltalk). Bye -- Markus Email: markus.liebelt@online.de