From: ara.t.howard@... Date: 2006-09-10T05:27:20+09:00 Subject: Re: state machine in ruby On Sun, 10 Sep 2006, Francis Cianfrocca wrote: > You'd have to add a parse stack and a lookahead buffer. Might not be that > easy, but I'll take a look if I get a chance. k. go easy on me. it's version 0.0.0 ;-) >> > And given that text, mechanically generate a state machine that would be >> > restartable so it could be event-driven. And the scanner would be pretty >> > funky too, it would have to be able to generate a token that means "not >> > enough input to scan a complete token, go to sleep now." >> >> naw, that's easy. just do > > > You solved that?? Nice. well - the event part: harp:~ > cat a.rb require "time" require "fsm" STDOUT.sync = true Thread.abort_on_exception = true fsys = FSM.system{ fsm{ states %w( a b c ) transition "a2b", "a" => "b" transition "b2c", "b" => "c" } #start # leave starting state and enter state "a" } Thread.new{ sleep 1 fsys.start # enters state 'a' sleep 1 fsys.fsm.transition "a", "a2b" sleep 1 fsys.fsm.transition "b", "b2c" } Thread.new{ puts "waiting for state a @ #{ Time.now.iso8601(6) }..." fsys.observer.wait_for "a" puts "state a waited for." puts "waiting for state b @ #{ Time.now.iso8601(6) }..." fsys.observer.wait_for "b" puts "state b waited for." puts "waiting for state c @ #{ Time.now.iso8601(6) }..." fsys.observer.wait_for "c" puts "state c waited for." }.join harp:~ > ruby a.rb waiting for state a @ 2006-09-09T14:03:42.527586-06:00... state a waited for. waiting for state b @ 2006-09-09T14:03:43.537855-06:00... state b waited for. waiting for state c @ 2006-09-09T14:03:44.547454-06:00... state c waited for. there a lots of other event hooks too. wait_for_once. etc. regarding the special token, that's easy - there are also hooks for input into the system: harp:~ > cat a.rb require "time" require "fsm" STDOUT.sync = true Thread.abort_on_exception = true MSGS = Queue.new and Thread.new{ loop{ puts MSGS.pop } } def t() Time.now.iso8601(6) end def p(msg) MSGS.push msg end fsys = FSM.system{ fsm{ states %w( a b c ) transition "a2b", "a" => "b" transition "b2c", "b" => "c" transition "c2a", "c" => "a" } observer{ on_entry do |info| p "entry <#{ info.inspect }> @ #{ t }" end on_input do |*argv| p "input <#{ argv.inspect }> @ #{ t }" end } start } Thread.new{ 1.times do sleep 1 fsys.input 'A' fsys.transition "a", "a2b" sleep 1 sleep 1 fsys.input 'B' fsys.transition "b", "b2c" sleep 1 sleep 1 fsys.input 'C' fsys.transition "c", "c2a" sleep 1 end }.join jib:~ > ruby a.rb entry <[FSM::Event::Entry, "a", nil]> @ 2006-09-09T14:23:43.335322-06:00 input <[[FSM::Event::Input, "a", "A"]]> @ 2006-09-09T14:23:44.338837-06:00 entry <[FSM::Event::Entry, "b", nil]> @ 2006-09-09T14:23:44.340079-06:00 input <[[FSM::Event::Input, "b", "B"]]> @ 2006-09-09T14:23:46.358668-06:00 entry <[FSM::Event::Entry, "c", nil]> @ 2006-09-09T14:23:46.359932-06:00 input <[[FSM::Event::Input, "c", "C"]]> @ 2006-09-09T14:23:48.378684-06:00 entry <[FSM::Event::Entry, "a", nil]> @ 2006-09-09T14:23:48.380190-06:00 so, for the special token, you simply remain in the current state - the observer is already sleeping ;-) is this what you are thinking of? >> what's AMQP ?? > > Advanced Message Queueing Protocol. Very interesting if you're into > message-queueing, it's the evolution of the "amq" that J.P.Morgan has been > working on for a couple of years and that you've heard periodic rumors about > during that time. It's different because it specifies not only the wire > protocol (which itself is state-of-the-art and worth a look) but also the > broker architecture. Needless to say, all the current work has been done in > Java, so they need an agile implementation. :-) learn something every day! cheers. -a -- what science finds to be nonexistent, we must accept as nonexistent; but what science merely does not find is a completely different matter... it is quite clear that there are many, many mysterious things. - h.h. the 14th dalai lama