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. Nodes will not differentiate between the String and Symbol versions of the values being indexed.
Direct Known Subclasses
Instance Attribute Summary (collapse)
-
- (Object) machine
The machine associated with the nodes.
Instance Method Summary (collapse)
-
- (Object) <<(node)
Adds a new node to the collection.
-
- (Object) [](key, index_name = @default_index)
Gets the node indexed by the given key.
-
- (Object) at(index)
Gets the node at the given index.
-
- (Object) concat(nodes)
Appends a group of nodes to the collection.
-
- (Object) context(nodes, &block)
Tracks a context that should be evaluated for any nodes that get added which match the given set of nodes.
-
- (Object) each
Calls the block once for each element in self, passing that element as a parameter.
-
- (Object) fetch(key, index_name = @default_index)
Gets the node indexed by the given key.
-
- (NodeCollection) initialize(machine, options = {})
constructor
Creates a new collection of nodes for the given state machine.
-
- (Object) initialize_copy(orig)
Creates a copy of this collection such that modifications don't affect the original collection.
-
- (Object) keys(index_name = @default_index)
Gets the set of unique keys for the given index.
-
- (Object) length
Gets the number of nodes in this collection.
-
- (Object) update(node)
Updates the indexed keys for the given node.
Methods included from Assertions
#assert_exclusive_keys, #assert_valid_keys
Constructor Details
- (NodeCollection) initialize(machine, options = {})
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
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/state_machine/node_collection.rb', line 21 def initialize(machine, = {}) assert_valid_keys(, :index) = {:index => :name}.merge() @machine = machine @nodes = [] @index_names = Array([:index]) @indices = @index_names.inject({}) do |indices, name| indices[name] = {} indices[:#{name}_to_s"] = {} indices[:#{name}_to_sym"] = {} indices end @default_index = Array([:index]).first @contexts = [] end |
Instance Attribute Details
- (Object) machine
The machine associated with the nodes
12 13 14 |
# File 'lib/state_machine/node_collection.rb', line 12 def machine @machine end |
Instance Method Details
- (Object) <<(node)
Adds a new node to the collection. By doing so, this will also add it to the configured indices. This will also evaluate any existings contexts that match the new node.
88 89 90 91 92 93 |
# File 'lib/state_machine/node_collection.rb', line 88 def <<(node) @nodes << node @index_names.each {|name| add_to_index(name, value(node, name), node)} @contexts.each {|context| eval_context(context, node)} self end |
- (Object) [](key, index_name = @default_index)
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.
145 146 147 148 149 150 |
# File 'lib/state_machine/node_collection.rb', line 145 def [](key, index_name = @default_index) self.index(index_name)[key] || self.index(:#{index_name}_to_s")[key.to_s] || to_sym?(key) && self.index(:#{index_name}_to_sym")[:#{key}"] || nil end |
- (Object) at(index)
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
131 132 133 |
# File 'lib/state_machine/node_collection.rb', line 131 def at(index) @nodes[index] end |
- (Object) concat(nodes)
Appends a group of nodes to the collection
96 97 98 |
# File 'lib/state_machine/node_collection.rb', line 96 def concat(nodes) nodes.each {|node| self << node} end |
- (Object) context(nodes, &block)
Tracks a context that should be evaluated for any nodes that get added which match the given set of nodes. Matchers can be used so that the context can get added once and evaluated after multiple adds.
75 76 77 78 79 80 81 82 83 |
# File 'lib/state_machine/node_collection.rb', line 75 def context(nodes, &block) nodes = nodes.first.is_a?(Matcher) ? nodes.first : WhitelistMatcher.new(nodes) @contexts << context = {:nodes => nodes, :block => block} # Evaluate the new context for existing nodes each {|node| eval_context(context, node)} context end |
- (Object) each
Calls the block once for each element in self, passing that element as a parameter.
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 --
118 119 120 121 |
# File 'lib/state_machine/node_collection.rb', line 118 def each @nodes.each {|node| yield node} self end |
- (Object) fetch(key, index_name = @default_index)
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
164 165 166 |
# File 'lib/state_machine/node_collection.rb', line 164 def fetch(key, index_name = @default_index) self[key, index_name] || raise(IndexError, "#{key.inspect} is an invalid #{index_name}") end |
- (Object) initialize_copy(orig)
Creates a copy of this collection such that modifications don't affect the original collection
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/state_machine/node_collection.rb', line 40 def initialize_copy(orig) #:nodoc: super nodes = @nodes contexts = @contexts @nodes = [] @contexts = [] @indices = @indices.inject({}) {|indices, (name, *)| indices[name] = {}; indices} # Add nodes *prior* to copying over the contexts so that they don't get # evaluated multiple times concat(nodes.map {|n| n.dup}) @contexts = contexts.dup end |
- (Object) keys(index_name = @default_index)
Gets the set of unique keys for the given index
68 69 70 |
# File 'lib/state_machine/node_collection.rb', line 68 def keys(index_name = @default_index) index(index_name).keys end |
- (Object) length
Gets the number of nodes in this collection
63 64 65 |
# File 'lib/state_machine/node_collection.rb', line 63 def length @nodes.length end |
- (Object) update(node)
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.
103 104 105 |
# File 'lib/state_machine/node_collection.rb', line 103 def update(node) @index_names.each {|name| update_index(name, node)} end |