Hi everyone,
I am trying to use IO.popen in order to put (with .puts method) and to get (with .gets method) messages from a process to its sub-process.
I am not very experimented and I have a question about. Having the following code, I have an error because it is not possible to write in a closed stream.
class Interface
def initialize(path)
@sub_process = IO.popen(path, 'w+')
end
def start!
if ok?
@sub_process.puts 'Hello', 'my name is ...'
# and more...
end
end
protected
def ok?
is_ready?(@sub_process) && is_cool?(@sub_process)
end
def is_ready?(sub_process)
reply = process_command(sub_process, 'are u ready?')
reply.chomp.match(/yes_i_am_ready$/)
end
def is_cool?(sub_process)
reply = process_command(sub_process, 'are u cool?')
reply.chomp.match(/yes_i_am_cool$/)
end
def process_command(sub_process, command)
rdr = Thread.new { sub_process.read } # alternative: io.readlines
sub_process.puts "#{command}"
sub_process.close_write
rdr.value # joins and fetches the result
end
end
a = Interface.new("./program")
a.start!
(...) in `write': not opened for writing (IOError)
As we can see, this error occur during is_cool? test (as explained at: http://ruby-doc.org/core/classes/IO.html#M002289).
But if I try to comment in process_command method the line:
# sub_process.close_write
the script seems to sleep... infinitely :s
I believe that it is not possible to open again a closed stream. And I can't create an other IO.popen instance of my program "./program" because it needs to be initialized with some command (like 'are u ready?' and 'are u cool?') at the beginning, before I use it (by sending and receiving messages like a simple discussion).
How changes can I do over the current code in order to solve this problem?
Edit: in other words, I would like to establish a such communication (according to a given protocol):
Parent message: Child answer:
-------------- ------------
'are u ready?' 'yes_i_am_ready'
'are u cool?' 'yes_i_am_cool'
'Hello' 'foo'
'my name is ...' 'bar'
Many thanks for any help.