(state_machine gem) 如何在状态机中使用实例变量?
(state_machine gem) How can I use instance variables within a state machine?
我正在尝试通过将口香糖机实现为状态机来跟随讲座。目的是用 0 个硬币和 10 个口香糖初始化它。默认情况下,它已准备就绪;你投入一枚硬币,然后从那里 request_refund 或 turn_crank。转动曲柄会使硬币计数器递增 1,同时递减硬币计数器(并返回随机的口香糖颜色)。如果剩下 0 个口香糖球,则转动曲柄没有任何作用。
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
。我来回阅读了文档并用谷歌搜索了它,但我不知道这有什么问题或者我应该做什么。
实例变量在状态机中不可访问,但当您创建它时attr_accessor您可以通过传递 gumball 机器对象来访问它。
有一个 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
event
块中的上下文与方法定义中的上下文不同。我猜 self
指的是事件,而不是在事件块中调用时的 GumballMachine
。
state_machine
docs 包含一个示例来说明这一点:
event :crash do
transition all - [:parked, :stalled] => :stalled, :if => lambda {|vehicle| !vehicle.passed_inspection?}
end
end
例子中vehicle
指实例,passed_inspection?
是实例上的方法
对于您的情况,您可以考虑添加一个方法(例如 has_gumball?
),然后可以访问实例变量。
我正在尝试通过将口香糖机实现为状态机来跟随讲座。目的是用 0 个硬币和 10 个口香糖初始化它。默认情况下,它已准备就绪;你投入一枚硬币,然后从那里 request_refund 或 turn_crank。转动曲柄会使硬币计数器递增 1,同时递减硬币计数器(并返回随机的口香糖颜色)。如果剩下 0 个口香糖球,则转动曲柄没有任何作用。
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
。我来回阅读了文档并用谷歌搜索了它,但我不知道这有什么问题或者我应该做什么。
实例变量在状态机中不可访问,但当您创建它时attr_accessor您可以通过传递 gumball 机器对象来访问它。
有一个 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
event
块中的上下文与方法定义中的上下文不同。我猜 self
指的是事件,而不是在事件块中调用时的 GumballMachine
。
state_machine
docs 包含一个示例来说明这一点:
event :crash do
transition all - [:parked, :stalled] => :stalled, :if => lambda {|vehicle| !vehicle.passed_inspection?}
end
end
例子中vehicle
指实例,passed_inspection?
是实例上的方法
对于您的情况,您可以考虑添加一个方法(例如 has_gumball?
),然后可以访问实例变量。