2015-12-03 62 views
0

我試圖通過實施一個口香糖機作爲一個狀態機跟着演講。意圖是它用0個硬幣和10個gumballs初始化。默認情況下,它已準備好;您插入一枚硬幣,然後從那裏輸入request_refund或turn_crank。轉動曲柄會使硬幣計數器增加1,同時減少硬幣計數器(並返回隨機的gumball顏色)。如果剩下0個口香糖,那麼轉動曲柄就什麼都不做。(state_machine gem)如何在狀態機中使用實例變量?

class GumballMachine 
    attr_reader :coins, :gumballs 

    def initialize 
    @coins = 0 
    @gumballs = 10 
    super 
    end 

    def dispense_gumball 
    @coins += 1 
    @gumballs -= 1 
    [:red, :green, :blue, :purple, :pink].sample 
    end 

    state_machine :state, initial: :ready do 
    event :insert_coin { transition :ready => :holding_coin } 

    event :request_refund { transition :holding_coin => :ready } 

    event :turn_crank do 
     dispense_gumball if @gumballs > 0 
     transition :holding_coin => :ready 
    end 
    end 
end 

此操作失敗,不過,在聲明if @gumballs > 0,因爲@gumballs尚未在這一點上定義。我已經反覆閱讀了文檔,並且把它從Google中刪除了,但是我沒有想到這個或者我應該做什麼。

回答

2

實例變量在狀態機中不可訪問,但是您可以通過傳遞gumball機器對象來訪問實例變量attr_accessor。

有一個before_transition回調,你的配藥。

before_transition holding_coin: :ready do |machine, transition| 
    machine.dispense_gumball if machine.gumballs > 0 
end 

event :turn_crank do 
    transition :holding_coin => :ready 
end 
+0

謝謝你,這解決了一切,我現在明白了很多。 – GreenTriangle

1

event塊內的上下文與方法定義中的上下文不同。我猜self指的是事件,而不是事件塊中調用的GumballMachine

state_machinedocs包括示出這樣的示例:

event :crash do 
    transition all - [:parked, :stalled] => :stalled, :if => lambda {|vehicle| !vehicle.passed_inspection?} 
    end 
end 

在該示例vehicle指實例,並passed_inspection?是對實例的方法。

對於您的情況,您可以考慮添加一個方法(例如has_gumball?),然後可以訪問該實例變量。

相關問題