Joel VanderWerf <vjoel / path.berkeley.edu> wrote: >> I am trying to write a some code that expresses a series of >> Commands/Responses over a serial link. >> >> In pseudocode, this is what I want to accomplish: >> >> conv = Conversation.new(connection) { |x| >> x.transmit(:init) >> x.wait_for(:ok) >> x.transmit(:get_user_input) >> x.wait_for(:user_data) { |message| response = message.text } >> puts response >> rescue TimeoutException => e >> x.retry if x.attempts < 3 >> } >> conv.start > > I'm guessing #start runs the block? Why not > > Thread.new {conv.start} I am pretty sure that I need Threads, but I think a single 'receiver'-Thread inside the connection instance should be enough. My main problem at this point is that I don't know how I want the final result to *look* like. > Or does the block get executed during Conversation.new, which just > queues up all the commands so that start can call them in order later? No, the "conversation" should be an arbitrary program. My current attempts wrap around an instance of IO, like so: # Connection wraps protocol details like a notion of "Packets" and # generates events if specific messages arrive connection = Connection.new( f = Tempfile.new("example") ) # Add a Packet named :init that can be sent by # calling "connection.send_packet(:init)" connection.add_sender(:init, Packet.create(:data_format => "INIT") ) # Add an event called :ok that is generated whenever a packet # starting with the letter "O" is received connection.add_receiver(:ok, Packet.create(:header => [?O]) ) # Register an event handler connection.on_receive(:ok) { |m| puts "received message: OK" } Given that I could probably do this: # Resumable from <http://www.all-thing.net/Ruby/coroutines.html> conversation = Resumable.new { |r| connection.on_receive(:ok) { r.resume if r.suspended? } connection.send(:init) r.suspend puts "Got an answer!" } ... connection.start # start sending/receiving data conversation.call ... That's not very pretty though -Levin