state_machine
https://github.com/pluginaweek/state_machine
Ruby
Adds support for creating state machines for attributes on any Ruby class
StateMachine::Machine#paths_for
Generates a list of the possible transition sequences that can be run on
the given object. These paths can reveal all of the possible states and
events that can be encountered in the object's state machine based on the
object's current state.
Configuration options:
* +from+ - The initial state to start all paths from. By default, this
is the object's current state.
* +to+ - The target state to end all paths on. By default, paths will
end when they loop back to the first transition on the path.
* +deep+ - Whether to allow the target state to be crossed more than once
in a path. By default, paths will immediately stop when the target
state (if specified) is reached. If this is enabled, then paths can
continue even after reaching the target state; they will stop when
reaching the target state a second time.
*Note* that the object is never modified when the list of paths is
generated.
== Examples
class Vehicle
state_machine :initial => :parked do
event :ignite do
transition :parked => :idling
end
event :shift_up do
transition :idling => :first_gear, :first_gear => :second_gear
end
event :shift_down do
transition :second_gear => :first_gear, :first_gear => :idling
end
end
end
vehicle = Vehicle.new # => #<Vehicle:0xb7c27024 @state="parked">
vehicle.state # => "parked"
vehicle.state_paths
# => [
# [#<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>,
# #<StateMachine::Transition attribute=:state event=:shift_up from="idling" from_name=:idling to="first_gear" to_name=:first_gear>,
# #<StateMachine::Transition attribute=:state event=:shift_up from="first_gear" from_name=:first_gear to="second_gear" to_name=:second_gear>,
# #<StateMachine::Transition attribute=:state event=:shift_down from="second_gear" from_name=:second_gear to="first_gear" to_name=:first_gear>,
# #<StateMachine::Transition attribute=:state event=:shift_down from="first_gear" from_name=:first_gear to="idling" to_name=:idling>],
#
# [#<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>,
# #<StateMachine::Transition attribute=:state event=:shift_up from="idling" from_name=:idling to="first_gear" to_name=:first_gear>,
# #<StateMachine::Transition attribute=:state event=:shift_down from="first_gear" from_name=:first_gear to="idling" to_name=:idling>]
# ]
vehicle.state_paths(:from => :parked, :to => :second_gear)
# => [
# [#<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>,
# #<StateMachine::Transition attribute=:state event=:shift_up from="idling" from_name=:idling to="first_gear" to_name=:first_gear>,
# #<StateMachine::Transition attribute=:state event=:shift_up from="first_gear" from_name=:first_gear to="second_gear" to_name=:second_gear>]
# ]
In addition to getting the possible paths that can be accessed, you can
also get summary information about the states / events that can be
accessed at some point along one of the paths. For example:
# Get the list of states that can be accessed from the current state
vehicle.state_paths.to_states # => [:idling, :first_gear, :second_gear]
# Get the list of events that can be accessed from the current state
vehicle.state_paths.events # => [:ignite, :shift_up, :shift_down]Edit
git clone [email protected]:pluginaweek/state_machine.git
cd state_machine
open lib/state_machine/machine.rb
Contribute
# Make a new branchgit checkout -b -your-name--update-docs-StateMachine--Machine-paths_for-for-pr
# Commit to gitgit add lib/state_machine/machine.rbgit commit -m "better docs for StateMachine::Machine#paths_for"
# Open pull requestgem install hub # on a mac you can `brew install hub`
hub fork
git push <your name> -your-name--update-docs-StateMachine--Machine-paths_for-for-pr
hub pull-request
# Celebrate!