Class: Constants::ConstantLibrary
- Inherits:
-
Object
- Object
- Constants::ConstantLibrary
- Defined in:
- lib/constants/constant_library.rb
Overview
ConstantLibrary facilitates indexing and collection of a set of values.
lib = ConstantLibrary.new('one', 'two', :three)
lib.index_by('upcase') {|value| value.to_s.upcase }
lib.indicies['upcase'] # => {'ONE' => 'one', 'TWO' => 'two', 'THREE' => :three}
lib.collect("string") {|value| value.to_s }
lib.collections['string'] # => ['one', 'two', 'three']
See Constants::Library for more details.
Defined Under Namespace
Classes: Collection, Index
Instance Attribute Summary collapse
-
#collections ⇒ Object
readonly
A hash of (name, collection) pairs tracking the collections in self.
-
#indicies ⇒ Object
readonly
A hash of (name, index) pairs tracking the indicies in self.
-
#values ⇒ Object
readonly
An array of values in the library.
Instance Method Summary collapse
-
#[](key) ⇒ Object
Lookup values by a key.
-
#add(*values) ⇒ Object
Add the specified values to self.
-
#add_constants_from(mod) ⇒ Object
Adds the constants from the specified module.
-
#clear(complete = false) ⇒ Object
Clears all values, from self, indicies, and collections.
-
#collect(name, &block) ⇒ Object
Adds a collection to self for all values currently in self.
-
#collect_attribute(attribute) ⇒ Object
Adds a collection using the attribute or method.
-
#index_by(name, exclusion_value = nil, nil_value = nil, &block) ⇒ Object
Adds an index to self for all values currently in self.
-
#index_by_attribute(attribute, exclusion_value = nil, nil_value = nil) ⇒ Object
Adds an index using the attribute or method.
-
#initialize(*values) ⇒ ConstantLibrary
constructor
A new instance of ConstantLibrary.
Constructor Details
#initialize(*values) ⇒ ConstantLibrary
Returns a new instance of ConstantLibrary.
119 120 121 122 123 |
# File 'lib/constants/constant_library.rb', line 119 def initialize(*values) @values = values.uniq @indicies = {} @collections = {} end |
Instance Attribute Details
#collections ⇒ Object (readonly)
A hash of (name, collection) pairs tracking the collections in self
117 118 119 |
# File 'lib/constants/constant_library.rb', line 117 def collections @collections end |
#indicies ⇒ Object (readonly)
A hash of (name, index) pairs tracking the indicies in self
114 115 116 |
# File 'lib/constants/constant_library.rb', line 114 def indicies @indicies end |
#values ⇒ Object (readonly)
An array of values in the library
111 112 113 |
# File 'lib/constants/constant_library.rb', line 111 def values @values end |
Instance Method Details
#[](key) ⇒ Object
Lookup values by a key. All indicies will be searched in order; the first matching value is returned. Returns nil if no matches are found.
226 227 228 229 230 231 232 |
# File 'lib/constants/constant_library.rb', line 226 def [](key) indicies.values.each do |index| return index[key] if index.has_key?(key) end nil end |
#add(*values) ⇒ Object
Add the specified values to self. New values are incorporated into existing indicies and collections. Returns the values added (ie values minus any already-existing values).
247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/constants/constant_library.rb', line 247 def add(*values) new_values = values - self.values self.values.concat(new_values) [indicies, collections].each do |stashes| stashes.values.each do |stash| stash.stash(new_values) end end #new_values.each(&add_block) if add_block new_values end |
#add_constants_from(mod) ⇒ Object
Adds the constants from the specified module. If mod is a Class, then only constants that are a kind of mod will be added. This behavior can be altered by providing a block which each constant value; values are only included if the block evaluates to true.
265 266 267 268 269 270 271 272 |
# File 'lib/constants/constant_library.rb', line 265 def add_constants_from(mod) const_names = mod.constants.select do |const_name| const = mod.const_get(const_name) block_given? ? yield(const) : (mod.kind_of?(Class) ? const.kind_of?(mod) : true) end add(*const_names.collect {|const_name| mod.const_get(const_name) }) end |
#clear(complete = false) ⇒ Object
Clears all values, from self, indicies, and collections. The indicies, and collections themselves are preserved unless complete==true.
236 237 238 239 240 241 242 |
# File 'lib/constants/constant_library.rb', line 236 def clear(complete=false) values.clear [indicies, collections].each do |stashes| complete ? stashes.clear : stashes.values.each {|stash| stash.clear} end end |
#collect(name, &block) ⇒ Object
Adds a collection to self for all values currently in self. The block is used to calculate the values in the collection. The block receives each value in self and should return one of the following:
-
a value to be pushed onto the collection
-
a [value, index] array when an alternate value should be stored in the place of value, or when the value should be at a special index in the collection. When multiple values are directed to the same index, they are stashed into an array.
-
nil to exclude the value from the collection
For example:
lib = ConstantLibrary.new('one', 'two', :three)
lib.collect("string") {|value| value.to_s }
lib.collections['string'] # => ['one', 'two', 'three']
lib.collect("length") {|value| [value, value.to_s.length] }
lib.collections['length'] # => [nil, nil, nil, ['one', 'two'], nil, :three]
Works much like index_by, except that the underlying data store for a collection is a Collection (ie an array) rather than an Index (a hash).
207 208 209 210 211 212 213 |
# File 'lib/constants/constant_library.rb', line 207 def collect(name, &block) # :yields: value raise ArgumentError.new("no block given") unless block_given? collection = Collection.new(&block) collections[name] = collection collection.stash(values) end |
#collect_attribute(attribute) ⇒ Object
Adds a collection using the attribute or method. Equivalent to:
lib.collect(attribute) {|value| value.attribute }
219 220 221 222 |
# File 'lib/constants/constant_library.rb', line 219 def collect_attribute(attribute) method = attribute.to_sym collect(attribute) {|value| value.send(method) } end |
#index_by(name, exclusion_value = nil, nil_value = nil, &block) ⇒ Object
Adds an index to self for all values currently in self. The block is used to specify keys for each value in self; it receives each value and should return one of the following:
-
a key
-
a [key, value] array when an alternate value should be stored in the place of value
-
the exclusion_value to exclude the value from the index
When multiple values return the same key, they are stashed into an array.
lib = ConstantLibrary.new('one', 'two', :one)
lib.index_by("string") {|value| value.to_s }
lib.indicies['string']
# => {
# 'one' => ['one', :one],
# 'two' => 'two'}
Existing indicies by the specified name are overwritten.
nil values
The index stores it’s data in an Index (ie a Hash) where nil_value acts as the default value returned for non-existant keys as well as the stash nil_value. Hence index_by will raise an error if you try to store the nil_value.
This behavior can be seen when the exclusion value is set to something other than nil, so that the nil value isn’t skipped outright:
# the nil will cause trouble
lib = ConstantLibrary.new(1,2,nil)
lib.index_by("error", false, nil) {|value| value } # ! ArgumentError
Specify an alternate nil_value (and exclusion value) to index nils; a plain old Object works well.
obj = Object.new
index = lib.index_by("ok", false, obj) {|value| value }
index[1] # => 1
index[nil] # => nil
# remember the nil_value is the default value
index['non-existant'] # => obj
169 170 171 172 173 174 175 |
# File 'lib/constants/constant_library.rb', line 169 def index_by(name, exclusion_value=nil, nil_value=nil, &block) # :yields: value raise ArgumentError.new("no block given") unless block_given? index = Index.new(exclusion_value, nil_value, &block) indicies[name] = index index.stash(values) end |
#index_by_attribute(attribute, exclusion_value = nil, nil_value = nil) ⇒ Object
Adds an index using the attribute or method. Equivalent to:
lib.index_by(attribute) {|value| value.attribute }
181 182 183 184 |
# File 'lib/constants/constant_library.rb', line 181 def index_by_attribute(attribute, exclusion_value=nil, nil_value=nil) method = attribute.to_sym index_by(attribute, exclusion_value, nil_value) {|value| value.send(method) } end |