class StateMachine::Path

A path represents a sequence of transitions that can be run for a particular object. Paths can walk to new transitions, revealing all of the possible branches that can be encountered in the object's state machine.

Attributes

machine[R]

The state machine this path is walking

object[R]

The object whose state machine is being walked

Public Class Methods

new(object, machine, options = {}) click to toggle source

Creates a new transition path for the given object. Initially this is an empty path. In order to start walking the path, it must be populated with an initial transition.

Configuration options:

  • :target - The target state to end the path on

  • :guard - Whether to guard transitions with the if/unless conditionals defined for each one

   # File lib/state_machine/path.rb
22 def initialize(object, machine, options = {})
23   assert_valid_keys(options, :target, :guard)
24   
25   @object = object
26   @machine = machine
27   @target = options[:target]
28   @guard = options[:guard]
29 end

Public Instance Methods

complete?() click to toggle source

Determines whether or not this path has completed. A path is considered complete when one of the following conditions is met:

  • The last transition in the path ends on the target state

  • There are no more transitions remaining to walk and there is no target state

   # File lib/state_machine/path.rb
85 def complete?
86   !empty? && (@target ? to_name == @target : transitions.empty?)
87 end
events() click to toggle source

Lists all of the events that can be fired through this path.

For example,

path.events # => [:park, :ignite, :shift_up, ...]
   # File lib/state_machine/path.rb
70 def events
71   map {|transition| transition.event}.uniq
72 end
from_name() click to toggle source

The initial state name for this path

   # File lib/state_machine/path.rb
37 def from_name
38   first && first.from_name
39 end
from_states() click to toggle source

Lists all of the from states that can be reached through this path.

For example,

path.to_states  # => [:parked, :idling, :first_gear, ...]
   # File lib/state_machine/path.rb
46 def from_states
47   map {|transition| transition.from_name}.uniq
48 end
to_name() click to toggle source

The end state name for this path. If a target state was specified for the path, then that will be returned if the path is complete.

   # File lib/state_machine/path.rb
52 def to_name
53   last && last.to_name
54 end
to_states() click to toggle source

Lists all of the to states that can be reached through this path.

For example,

path.to_states  # => [:parked, :idling, :first_gear, ...]
   # File lib/state_machine/path.rb
61 def to_states
62   map {|transition| transition.to_name}.uniq
63 end
walk() { |push| ... } click to toggle source

Walks down the next transitions at the end of this path. This will only walk down paths that are considered valid.

   # File lib/state_machine/path.rb
76 def walk
77   transitions.each {|transition| yield dup.push(transition)}
78 end

Private Instance Methods

can_walk_to?(transition) click to toggle source

Determines whether it's possible to walk to the given transition from the current path. A transition can be walked to if:

  • It has not been recently walked and

  • If a target is specified, it has not been walked to twice yet

    # File lib/state_machine/path.rb
110 def can_walk_to?(transition)
111   !recently_walked?(transition) && (!@target || times_walked_to(@target) < 2)
112 end
recently_walked?(transition) click to toggle source

Determines whether the given transition has been recently walked down in this path. If a target is configured for this path, then this will only look at transitions walked down since the target was last reached.

    # File lib/state_machine/path.rb
 98 def recently_walked?(transition)
 99   transitions = self
100   if @target && @target != to_name && target_transition = detect {|t| t.to_name == @target}
101     transitions = transitions[index(target_transition) + 1..-1]
102   end
103   transitions.include?(transition)
104 end
times_walked_to(state) click to toggle source

Calculates the number of times the given state has been walked to

   # File lib/state_machine/path.rb
91 def times_walked_to(state)
92   select {|transition| transition.to_name == state}.length
93 end
transitions() click to toggle source

Get the next set of transitions that can be walked to starting from the end of this path

    # File lib/state_machine/path.rb
116 def transitions
117   @transitions ||= empty? ? [] : machine.events.transitions_for(object, :from => to_name, :guard => @guard).select {|transition| can_walk_to?(transition)}
118 end