2015-06-25 70 views
0

使用finite machine gem for Ruby來自Piotr Murach。peter-murach/finite_machine恢復持久狀態

想用持久(存儲)狀態恢復狀態機。該文檔教導初始狀態,並從ActiveRecord模型恢復狀態。

我所能找到的所有DSL都可以讓我定義一個初始狀態,或者定義一個轉換到初始狀態的事件。兩者都要求我在編碼時定義初始狀態。

fm = FiniteMachine.define do 
    initial :red 

fm = FiniteMachine.define do 
    events { 
    event :start, :none => :red 

在實踐中,我定義一個「獨立」的線沿線,

class Engine < FiniteMachine::Definition 
    initial :neutral 

我想什麼是定義在初始狀態該類的初始化器,如:

class Engine < FiniteMachine::Definition 
    def initialize(car, state) 
     initial state 
     target car 
    end 

但是,這不起作用。初始化後,我得到:none作爲當前狀態。

找到restore!方法和文檔中關於使用ActiveRecord保持狀態的部分。嘗試過的東西沿着線:

class Engine < FiniteMachine::Definition 
    def initialize(car, state) 
     restore! state 
     target car 
    end 

然而,構造函數返回一個類FiniteMachine::StateMachine調用它new時。 new方法可以使用任意數量的參數,並且該類的任何方法都不會被調用。它返回一個不同的類。

下面是從下面的程序輸出:

GSM class is FiniteMachine::StateMachine 
GSM current state is red 
.gems/gems/finite_machine-0.10.1/lib/finite_machine/state_machine.rb:259:in `valid_state?': inappropriate current state 'red' (FiniteMachine::InvalidStateError) 

程序:

require 'finite_machine' 

class GenericStateMachine < FiniteMachine::Definition 
    initial :red 

    def initialize(light) 
    puts "INITIALIZER WITH #{light}" 
    super 
    restore! light.state 
    target light 
    end 

    events { 
    event :start, :red => :green 
    event :stop, :green => :red 
    } 

    callbacks { 
    on_enter { |event| target.state = event.to } 
    } 
end 

class Light 
    attr_accessor :state 
    def initialize 
    state = 'green' 
    end 
    def to_s 
    "Light in state #{state}" 
    end 
end 

light = Light.new 
gsm = GenericStateMachine.new(light) 
puts "GSM class is #{gsm.class.to_s}" 
puts "GSM current state is #{gsm.current}" 
gsm.stop 
puts "GSM state after stop is #{gsm.current}" 
puts "Light state after stop is #{light.state}" 

回答

0

什麼工作得更好是通過FiniteMachine.define

做一個狀態機 factory method,使用了DSL

以下是程序的輸出:

CREATING MACHINE with Light in state green 
GSM class is FiniteMachine::StateMachine 
GSM current state is green 
GSM state after stop is red 
Light state after stop is red 

程序:

require 'finite_machine' 

class LightMachineFactory 
    def self.create_machine(light) 
    FiniteMachine.define do 
     puts "CREATING MACHINE with #{light}" 
     initial light.state 
     target light 

     events { 
     event :start, :red => :green 
     event :stop, :green => :red 
     } 

     callbacks { 
     on_enter { |event| target.state = event.to } 
     } 
    end 
    end 
end 

class Light 
    attr_accessor :state 
    def initialize 
    @state = 'green' 
    end 
    def to_s 
    "Light in state #{state}" 
    end 
    def state 
    @state.to_sym 
    end 
end 

light = Light.new 
gsm = LightMachineFactory.create_machine(light) 
puts "GSM class is #{gsm.class.to_s}" 
puts "GSM current state is #{gsm.current}" 
gsm.stop 
puts "GSM state after stop is #{gsm.current}" 
puts "Light state after stop is #{light.state}" 

此內容是從(我)closed issue在用於寶石GitHub的源代碼庫共享。 (對於什麼是使用問題而言,這是一個比問題更好的論壇。)