From: Robert Klemme Date: 2010-07-18T00:11:06+09:00 Subject: Re: Driving irb from IO.popen 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/