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]

Source | Google | Stack overflow

Edit

git clone [email protected]:pluginaweek/state_machine.git

cd state_machine

open lib/state_machine/machine.rb

Contribute

# Make a new branch

git checkout -b -your-name--update-docs-StateMachine--Machine-paths_for-for-pr


# Commit to git

git add lib/state_machine/machine.rbgit commit -m "better docs for StateMachine::Machine#paths_for"


# Open pull request

gem 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!