Class: StateMachine::NodeCollection
- Inherits:
-
Object
- Object
- StateMachine::NodeCollection
- Includes:
- Enumerable, Assertions
- Defined in:
- lib/state_machine/node_collection.rb
Overview
Represents a collection of nodes in a state machine, be it events or states.
Direct Known Subclasses
Instance Method Summary collapse
-
#<<(node) ⇒ Object
Adds a new node to the collection.
-
#[](key, index_name = @default_index) ⇒ Object
Gets the node indexed by the given key.
-
#at(index) ⇒ Object
Gets the node at the given index.
-
#each ⇒ Object
Calls the block once for each element in self, passing that element as a parameters.
-
#fetch(key, index_name = @default_index) ⇒ Object
Gets the node indexed by the given key.
-
#initialize(options = {}) ⇒ NodeCollection
constructor
Creates a new collection of nodes for the given state machine.
-
#initialize_copy(orig) ⇒ Object
Creates a copy of this collection such that modifications don’t affect the original collection.
-
#keys(index_name = @default_index) ⇒ Object
Gets the set of unique keys for the given index.
-
#length ⇒ Object
Gets the number of nodes in this collection.
-
#machine=(new_machine) ⇒ Object
Changes the current machine associated with the collection.
-
#update(node) ⇒ Object
Updates the indexed keys for the given node.
Methods included from Assertions
#assert_exclusive_keys, #assert_valid_keys
Constructor Details
#initialize(options = {}) ⇒ NodeCollection
Creates a new collection of nodes for the given state machine. By default, the collection is empty.
Configuration options:
-
:index- One or more attributes to automatically generate hashed indices for in order to perform quick lookups. Default is to index by the :name attribute
16 17 18 19 20 21 22 23 |
# File 'lib/state_machine/node_collection.rb', line 16 def initialize( = {}) assert_valid_keys(, :index) = {:index => :name}.merge() @nodes = [] @indices = Array([:index]).inject({}) {|indices, attribute| indices[attribute] = {}; indices} @default_index = Array([:index]).first end |
Instance Method Details
#<<(node) ⇒ Object
Adds a new node to the collection. By doing so, this will also add it to the configured indices.
54 55 56 57 58 |
# File 'lib/state_machine/node_collection.rb', line 54 def <<(node) @nodes << node @indices.each {|attribute, index| index[node.send(attribute)] = node} self end |
#[](key, index_name = @default_index) ⇒ Object
Gets the node indexed by the given key. By default, this will look up the key in the first index configured for the collection. A custom index can be specified like so:
collection['parked', :value]
The above will look up the “parked” key in a hash indexed by each node’s value attribute.
If the key cannot be found, then nil will be returned.
114 115 116 |
# File 'lib/state_machine/node_collection.rb', line 114 def [](key, index_name = @default_index) index(index_name)[key] end |
#at(index) ⇒ Object
Gets the node at the given index.
states = StateMachine::NodeCollection.new
states << StateMachine::State.new(machine, :parked)
states << StateMachine::State.new(machine, :idling)
states.at(0).name # => :parked
states.at(1).name # => :idling
100 101 102 |
# File 'lib/state_machine/node_collection.rb', line 100 def at(index) @nodes[index] end |
#each ⇒ Object
Calls the block once for each element in self, passing that element as a parameters.
states = StateMachine::NodeCollection.new
states << StateMachine::State.new(machine, :parked)
states << StateMachine::State.new(machine, :idling)
states.each {|state| puts state.name, ' -- '}
…produces:
parked -- idling --
87 88 89 90 |
# File 'lib/state_machine/node_collection.rb', line 87 def each @nodes.each {|node| yield node} self end |
#fetch(key, index_name = @default_index) ⇒ Object
Gets the node indexed by the given key. By default, this will look up the key in the first index configured for the collection. A custom index can be specified like so:
collection['parked', :value]
The above will look up the “parked” key in a hash indexed by each node’s value attribute.
If the key cannot be found, then an IndexError exception will be raised:
collection['invalid', :value] # => IndexError: "invalid" is an invalid value
130 131 132 |
# File 'lib/state_machine/node_collection.rb', line 130 def fetch(key, index_name = @default_index) self[key, index_name] || raise(ArgumentError, "#{key.inspect} is an invalid #{index_name}") end |
#initialize_copy(orig) ⇒ Object
Creates a copy of this collection such that modifications don’t affect the original collection
27 28 29 30 31 32 33 34 |
# File 'lib/state_machine/node_collection.rb', line 27 def initialize_copy(orig) #:nodoc: super nodes = @nodes @nodes = [] @indices = @indices.inject({}) {|indices, (name, index)| indices[name] = {}; indices} nodes.each {|node| self << node.dup} end |
#keys(index_name = @default_index) ⇒ Object
Gets the set of unique keys for the given index
48 49 50 |
# File 'lib/state_machine/node_collection.rb', line 48 def keys(index_name = @default_index) index(index_name).keys end |
#length ⇒ Object
Gets the number of nodes in this collection
43 44 45 |
# File 'lib/state_machine/node_collection.rb', line 43 def length @nodes.length end |
#machine=(new_machine) ⇒ Object
Changes the current machine associated with the collection. In turn, this will change the state machine associated with each node in the collection.
38 39 40 |
# File 'lib/state_machine/node_collection.rb', line 38 def machine=(new_machine) each {|node| node.machine = new_machine} end |
#update(node) ⇒ Object
Updates the indexed keys for the given node. If the node’s attribute has changed since it was added to the collection, the old indexed keys will be replaced with the updated ones.
63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/state_machine/node_collection.rb', line 63 def update(node) @indices.each do |attribute, index| old_key = index.respond_to?(:key) ? index.key(node) : index.index(node) new_key = node.send(attribute) # Only replace the key if it's changed if old_key != new_key index.delete(old_key) index[new_key] = node end end end |