![]() |
Articles Feed |
Categories
Archives
- February 2010 (2)
- January 2010 (1)
- December 2009 (1)
- October 2009 (4)
- September 2009 (2)
- August 2009 (2)
- July 2009 (5)
- June 2009 (2)
- May 2009 (2)
- April 2009 (8)
- March 2009 (7)
- January 2009 (2)
- December 2008 (3)
- November 2008 (5)
- October 2008 (4)
- September 2008 (6)
- August 2008 (4)
- July 2008 (5)
- June 2008 (5)
- May 2008 (4)
- April 2008 (2)
- February 2008 (4)
- January 2008 (2)
- December 2007 (2)
- November 2007 (2)
- October 2007 (2)
- September 2007 (1)
- August 2007 (3)
- July 2007 (1)
- June 2007 (4)
- May 2007 (7)
- April 2007 (2)
- February 2007 (3)
- January 2007 (3)
- November 2006 (3)
- October 2006 (3)
- September 2006 (17)
- November 2004 (1)
Understanding Statemachines, Part 3: Conditional Logic
by: micah | February 12th, 2007 |
Conditions
If you’re doing any significant amount of work with statmachines, you will most certainly encounter some conditional logic in your statemachines. Take our vending machine. When ever a coin is inserted, the invoked event will depend on whether the total amount of money inserted is sufficient to buy something. If enough money has been tendered, the display should suggest that the customer make a selection. If insufficient money has been inserted, the customer should be prompted to insert more.
Conditional logic can be accomplished by using entry actions. See the diagram below.

State Diagram with Conditional Logic
Starting in the Accept Money state, when a coin is inserted, the coin event is fired and the statemachine transitions into the Coin Inserted state. This is where it gets fun. Upon entering of the Coin Inserted state its entry event is invoked: count_amount_tendered. This method will count the money and invoke the not_paid_yet or paid event accordingly. This will cause the statemachine to transition into the appropriate state.
The Coin Inserted state is unique. You wouldn’t expect to find the statemachine in the Coin Inserted state for any reason except to make this decision. Once the decision is made, the state changes. States like this are called Decision States.
Code
- require 'rubygems'
- require 'statemachine'
- class VendingMachineContext
- attr_accessor :statemachine
- def initialize
- @amount_tendered = 0
- end
- def add_coin
- @amount_tendered = @amount_tendered + 25
- end
- def count_amount_tendered
- if @amount_tendered >= 100
- @statemachine.paid
- else
- @statemachine.not_paid_yet
- end
- end
- def prompt_money
- puts "$.#{@amount_tendered}: more money please"
- end
- def prompt_selection
- puts "please make a selection"
- end
- end
- vending_machine = Statemachine.build do
- trans :accept_money, :coin, :coin_inserted, :add_coin
- state :coin_inserted do
- event :not_paid_yet, :accept_money, :prompt_money
- event :paid, :await_selection, :prompt_selection
- on_entry :count_amount_tendered
- end
- context VendingMachineContext.new
- end
- vending_machine.context.statemachine = vending_machine
- vending_machine.coin
- vending_machine.coin
- vending_machine.coin
- vending_machine.coin
Output:
$.25: more money please $.50: more money please $.75: more money please please make a selection
Next lesson: Superstates
Understanding Statemachines, Part 4: Superstates
