Class: StateMachine::StateCollection

Inherits:
NodeCollection show all
Defined in:
lib/state_machine/state_collection.rb

Overview

Represents a collection of states in a state machine

Instance Attribute Summary

Attributes inherited from NodeCollection

#machine

Instance Method Summary (collapse)

Methods inherited from NodeCollection

#<<, #[], #at, #concat, #context, #each, #fetch, #initialize_copy, #keys, #length, #update

Methods included from Assertions

#assert_exclusive_keys, #assert_valid_keys

Constructor Details

- (StateCollection) initialize(machine)

:nodoc:



6
7
8
# File 'lib/state_machine/state_collection.rb', line 6

def initialize(machine) #:nodoc:
  super(machine, :index => [:name, :qualified_name, :value])
end

Instance Method Details

- (Object) by_priority

Gets the order in which states should be displayed based on where they were first referenced. This will order states in the following priority:

  1. Initial state

  2. Event transitions (:from, :except_from, :to, :except_to options)

  3. States with behaviors

  4. States referenced via state or other_states

  5. States referenced in callbacks

This order will determine how the GraphViz visualizations are rendered.



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/state_machine/state_collection.rb', line 93

def by_priority
  order = select {|state| state.initial}.map {|state| state.name}
  
  machine.events.each {|event| order += event.known_states}
  order += select {|state| state.methods.any?}.map {|state| state.name}
  order += keys(:name) - machine.callbacks.values.flatten.map {|callback| callback.known_states}.flatten
  order += keys(:name)
  
  order.uniq!
  order.map! {|name| self[name]}
  order
end

- (Object) match(object)

Determines the current state of the given object as configured by this state machine. This will attempt to find a known state that matches the value of the attribute on the object.

Examples

class Vehicle
  state_machine :initial => :parked do
    other_states :idling
  end
end

states = Vehicle.state_machine.states

vehicle = Vehicle.new         # => #<Vehicle:0xb7c464b0 @state="parked">
states.match(vehicle)         # => #<StateMachine::State name=:parked value="parked" initial=true>

vehicle.state = 'idling'
states.match(vehicle)         # => #<StateMachine::State name=:idling value="idling" initial=true>

vehicle.state = 'invalid'
states.match(vehicle)         # => nil


55
56
57
58
# File 'lib/state_machine/state_collection.rb', line 55

def match(object)
  value = machine.read(object, :state)
  self[value, :value] || detect {|state| state.matches?(value)}
end

- (Object) match!(object)

Determines the current state of the given object as configured by this state machine. If no state is found, then an ArgumentError will be raised.

Examples

class Vehicle
  state_machine :initial => :parked do
    other_states :idling
  end
end

states = Vehicle.state_machine.states

vehicle = Vehicle.new         # => #<Vehicle:0xb7c464b0 @state="parked">
states.match!(vehicle)        # => #<StateMachine::State name=:parked value="parked" initial=true>

vehicle.state = 'invalid'
states.match!(vehicle)        # => ArgumentError: "invalid" is not a known state value


79
80
81
# File 'lib/state_machine/state_collection.rb', line 79

def match!(object)
  match(object) || raise(ArgumentError, "#{machine.read(object, :state).inspect} is not a known #{machine.name} value")
end

- (Boolean) matches?(object, name)

Determines whether the given object is in a specific state. If the object's current value doesn't match the state, then this will return false, otherwise true. If the given state is unknown, then an IndexError will be raised.

Examples

class Vehicle
  state_machine :initial => :parked do
    other_states :idling
  end
end

states = Vehicle.state_machine.states
vehicle = Vehicle.new               # => #<Vehicle:0xb7c464b0 @state="parked">

states.matches?(vehicle, :parked)   # => true
states.matches?(vehicle, :idling)   # => false
states.matches?(vehicle, :invalid)  # => IndexError: :invalid is an invalid key for :name index

Returns:

  • (Boolean)


29
30
31
# File 'lib/state_machine/state_collection.rb', line 29

def matches?(object, name)
  fetch(name).matches?(machine.read(object, :state))
end