2011-01-20
There is excellent ruby statemachine project with very good examples and documentation,
gem install statemachine
but when I was using statemachines in my project there was one annoying thing. When you create statemachine you define its structure in block and it takes good few lines on the screen.
Solution for this problem is very simple, you need to create your own builder class, that will do everything what is needed to setup machine correctly:
class ServerBuilder def self.build Statemachine.build do trans :stopped, :power_on, :booting, :power_on trans :booting, :done, :running trans :running, :done, :shutting_down trans :shutting_down, :done, :stopped context ServerContext.new end end end class ServerContext def power_on puts "Server is booting..." end end s = ServerBuilder.build puts s.state s.power_on puts s.state
Now we can easily put class definition to separate file and have something like this
require 'server_description' s = Server.build puts s.state s.power_on puts s.state
Sometimes is quite handy to keep reference to server inside its context, then we could have one central method in context that decide what to do based on current machine state.
require 'rubygems' require 'statemachine' class Server < Statemachine::Statemachine def self.build @fsm=Statemachine.build do |fsm| trans :stopped, :power_on, :booting, :action trans :booting, :done, :running, :action trans :running, :power_off, :shutting_down, :action trans :shutting_down, :done, :stopped, :action end @fsm.context=ServerContext.new(@fsm) @fsm end end class ServerContext def initialize(fsm) @fsm = fsm end def action case @fsm.state when :stopped then puts "Someone pressed power on button" when :booting then puts "Booting finished" when :running then puts "Someone pressed shutdown button" when :shuting_down then puts "Server is stopped now" end end end s = Server.build puts s.state s.power_on puts s.state s.done puts s.state s.power_off s.done puts s.state
After you run this script you should see:
$ ruby server_fsm.rb stopped Someone pressed power on button booting Booting finished Someone pressed shutdown button
That’s all for now.
Comment blog comments powered by Disqus