On 07/17/2010 02:05 PM, Jean-Julien Fleck wrote:
> I'm stuck with a problem concerning IO.popen
> It's not necessarily related to irb but that's a good point where to start.
>
> I'd like to drive irb from ruby using IO.popen. The problem is: each
> time I type something inside irb, I can get one, two or more lines of
> output I'd like to store with no way to know beforehand how many there
> will be.
>
> The thing is: I don't know how to detect when irb has ended its output
> and is waiting for me to give some input.
>
> I tried the following:
>
>    def irb(string)
>      output = ''
>      puts "Trying to talk to irb"
>      IO.popen('irb --simple-prompt','r+') do |io|
>        string.chomp.split.each do |s|
>          io.puts s
>          while line = io.gets
>            line = io.gets
>            puts line
>            output += line

Note: << is more efficient than += here.

>          end
>        end
>      end
>      return output
>    end
>
>    s = "2+2\n'2'+'2'\n'2'+2"
>
>    irb(s)
>
> I was hoping that io.gets would be nil when irb is waiting for input,
> but it's not. So this little program gets stuck after the first
> statement:
>
> brisingr ~/tmp>ruby essai_irb.rb
> Trying to talk to irb
> =>  4
>
> Rather, I would like him to return
>
>>> 2+2
> =>  4
>>> '2'+'2'
> =>  "22"
>>> '2'+2
> TypeError: can't convert Fixnum into String
>          from (irb):4:in `+'
>          from (irb):4
>
> Does someone have a workaround ?

Not a workaround but a solution: since you only want to collect the 
output of irb and do not need to react on it you can simply use a second 
thread that collects all the output.

   def irb_test(strings)
     puts "Trying to talk to irb"

     IO.popen('irb --simple-prompt','r+') do |io|
       rdr = Thread.new { io.read }

       io.puts strings

       io.close_write
       rdr.value
     end
   end

Kind regards

	robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/