Overview
This module, barebone-fsm, implements a basic finite-state machine (FSM). An FSM consists of a finite number of states, with one of them being the current state of the FSM. Transitions are defined between states, which are triggered on events. For details on FSM, see this wiki page: FSM.
The motivation behind the module was to implement a very basic barebone FSM in Ruby. Features are kept at minimum as well as the code. Only two classes for the FSM are defined as the following:
-
FSM::FSM -> the finite state machine class
-
FSM::FSMState -> the state class
The FSM Module when included in a class also provides few convenience methods. For further details see the README file.
- Author
-
Md. Imrul Hassan ([email protected])
- Copyright
-
Copyright © 2013, Md. Imrul Hassan
- License
-
Barebone-fsm is released under the MIT license
Features
Apart from having support for states and events, this module offers the following features:
-
Default state
-
Default event for each state
-
Entry and exit events for each state
-
DSL like coding style
-
Access to state variables (including @state and @event) inside event blocks
-
The module when included in a Class, provides methods to setup the state machine and trigger events
-
Dynamic methods generated for the Class to check states, events and trigger events.
Usage
The FSM can be setup and triggered Succinctly using Domain Specific Language(DSL) like coding style. There are two methods to build and run which are defined for both FSM and FSMState classes. These methods, #build and #run, are alias of each other and can be used interchangebly. A basic fintite-state machine for a microwave is simulated in the following example:
fsm = FSM::FSM.new(:stopped)
fsm.build do
state :stopped do
event :open do
puts "[Stopped]: Door Opened"
:open
end
event :start do
puts "[Stopped]: Started"
:started
end
end
state :open do
event :close do
puts "[#{@state}]: Door #{@event}"
:stopped
end
end
state :started do
event :open do
@open_time = Time::now
puts "[Started]: Door Opened"
:open
end
event :stop do
puts "The door was opened at #{@open_time}"
puts "[Started]: Door Stopped after #{elapsed_time}"
:stopped
end
end
end
fsm.run do
event :start
event :open
event :close
event :start
event :stop
end
Status
The module works as it is, I have added some testing and documentation; it may be expanded. The api is not stable yet, it may go trhough lots of changes before the first stable version is released. I am open to any suggestion or request to support custom features.
Changes
-
Version: 0.0.3
-
Added Module level methods for easy access to states and events.
-
Added documentations for all the methods.
-
Added Module level dynamic methods to check states, events and to trigger events.
-
Added some testing codes using RSpec.
-
-
Version: 0.0.2
-
State variables defined in other states can be accessed in the event block as well.
-
-
Version: 0.0.1.3
-
Minor fixes on the usage examples.
-
-
Version: 0.0.1.2
-
@state instance variable for FSM is dropped in favour of the #state instance method.
-
#state method and index operator [] now accept nil arguement for state name, which returns the current state.
-
Two methods #build and #run are added to FSM and FSMState classes to support DSL like features.
-
Explicit parameter passing for the event blocks is no longer available. Instead the block code for the events now have access to all instance variables of FSMState class such as @state and @event.
-