class Nucleon::Config
Base configuration object¶ ↑
The Nucleon::Config
class defines a tree data container that can easily be merged and persisted to different mediums.
The configuration is at the core of the Nucleon
framework. The configuration allows us to store, lookup, and perform other operations (such as merge) on our class data by treating a subset of class properties as a tree based data structure.
Four main goals with this object:
-
Centralized property trees for objects
-
Easy access and management of nested properties
-
Mergeable objects (deep or shallow merges of tree based data)
-
Provide basic data translation utilities to sub classes
Global interface¶ ↑
The Nucleon::Config
class uses two static mixins that provide a central registry for option groups and property collections.
Option groups are contextualized collections of properties
-
see
Nucleon::Config::Options
(collection implementation) -
see
Nucleon::Mixin::ConfigOptions
(embeddable method interface)
Property collections are flexible groups of properties that can be logged to file system.
-
see
Nucleon::Config::Collection
(collection implementation) -
see
Nucleon::Mixin::ConfigCollection
(embeddable method interface)
Instance generators¶ ↑
The core configuration object provides a few instance generators that allow for easier initialization of configurations.
Public Class Methods
Ensure a data object is an array.
See:
# File lib/core/config.rb 904 def self.array(data, default = [], split_string = false) 905 return Util::Data.array(data, default, split_string) 906 end
Ensure the return of a Nucleon::Config
object based on different inputs.
This method can also initialize defaults for the configuration object if the configurations do not exist yet.
For example: (you will see variants of this pattern everywhere)
def some_method(options = {}) # Options might be a Config object or Hash? config = Config.ensure(options, { :my_property => 'default value' }) prop = config[:my_property] end
-
Parameters
- nil,
Hash
,Nucleon::Config
-
config Configurations to evaluate and possibly convert
- nil,
Hash
-
defaults Configuration defaults that may be overridden by config data
- Boolean
-
force Whether or not to force override of values where types don’t match during merge
- Boolean
-
basic_merge Whether or not to perform a basic merge or deep (recursive) merge
-
Returns
Nucleon::Config
-
Returns configuration object
-
Errors
See:
# File lib/core/config.rb 93 def self.ensure(config, defaults = {}, force = true, basic_merge = true) 94 case config 95 when Nucleon::Config 96 return config.defaults(defaults, { :force => force, :basic => basic_merge }) 97 when Hash 98 return new(config, defaults, force, basic_merge) 99 end 100 return new({}, defaults, force, basic_merge) 101 end
Run a defined filter on a data object.
This method ensures that a given data object meets some criteria or else an empty value for that type is returned that matches the criteria.
Currently implemented filters:
-
::array
Ensure result is an array (non arrays are converted) -
::hash
Ensure result is a hash (non hashes are converted) -
::string
Ensure result is a string (non strings are converted) -
::symbol
Ensure result is a symbol (non symbols are converted) -
::test
Ensure result is not empty (runs a boolean ::empty? check)
See:
# File lib/core/config.rb 884 def self.filter(data, method = false) 885 return Util::Data.filter(data, method) 886 end
Ensure a data object is a hash.
See:
# File lib/core/config.rb 922 def self.hash(data, default = {}) 923 data = data.export if data.is_a?(Nucleon::Config) 924 return Util::Data.hash(data, default) 925 end
Initialize a new configuration object with contextualized defaults from the global configuration option collection.
This method is not really used much within Nucleon
itself, but is used to help create the corl gem Puppet interface that forms the provisioner configurations for resource creation based on options defined in Puppet.
This method supports hierarchical lookup of context properties.
Example:
Nucleon::Config::set_options([ :context1, :prefix_context2 ], { :my_property => 'value' }) config = Nucleon::Config.init({ :other_property => 'something' }, :context2, :prefix) config.export # { # :my_property => 'value', # :other_property => 'something' # }
-
Parameters
- nil,
Hash
,Nucleon::Config
-
config Configurations to evaluate and possibly convert
- nil,
- Array<String, Symbol>, String, Symbol
-
contexts Context names to include in list
- Array<String, Symbol>, String, Symbol
-
hierarchy Hierarchy of prefixes to apply to given contexts
Hash
-
defaults Configuration defaults that may be overridden by config data
- Boolean
-
force Whether or not to force override of values where types don’t match during merge
- Boolean
-
basic_merge Whether or not to perform a basic merge or deep (recursive) merge
-
Returns
Nucleon::Config
-
Returns configuration object
-
Errors
See also:
# File lib/core/config.rb 144 def self.init(options, contexts = [], hierarchy = [], defaults = {}, force = true, basic_merge = true) 145 contexts = contexts(contexts, hierarchy) 146 config = new(get_options(contexts), defaults, force, basic_merge) 147 config.import(options) unless Util::Data.empty?(options) 148 return config 149 end
Initialize a new configuration object with contextualized defaults from the global configuration option collection (no hierarchical support).
This method is not really used much within Nucleon
itself, but is used to help create the corl gem Puppet interface that forms the provisioner configurations for resource creation based on options defined in Puppet.
Example:
Nucleon::Config::set_options([ :context1, :context2 ], { :my_property => 'value' }) config = Nucleon::Config.init_flat({ :other_property => 'something' }, :context2) config.export # { # :my_property => 'value', # :other_property => 'something' # }
-
Parameters
- nil,
Hash
,Nucleon::Config
-
config Configurations to evaluate and possibly convert
- nil,
- Array<String, Symbol>, String, Symbol
-
contexts Context names to include in list
Hash
-
defaults Configuration defaults that may be overridden by config data
- Boolean
-
force Whether or not to force override of values where types don’t match during merge
- Boolean
-
basic_merge Whether or not to perform a basic merge or deep (recursive) merge
-
Returns
Nucleon::Config
-
Returns configuration object
-
Errors
See:
# File lib/core/config.rb 184 def self.init_flat(options, contexts = [], defaults = {}, force = true, basic_merge = true) 185 return init(options, contexts, [], defaults, force, basic_merge) 186 end
Initialize a new configuration object with given options and defaults.
The defaults are split out from the original options because we have found it handy to have them initialized from two different data objects. Defaults are only set if the original data lacks the default property name.
The configuration object is ultimately designed to provide a starting point for creating distributed objects, which are easily loaded, dumped, and merged to form composite objects.
The configuration serves as the framework base class to all Nucleon
plugins, core objects, and a few utilities. This class is the most important object in the entire Nucleon
framework, as it is used the most.
Example:
config = Nucleon::Config.new({ :other_property => 'something' }, { :my_property => 'default', :other_property => 'default' }) config.export # { # :my_property => 'default', # :other_property => 'something' # }
-
Parameters
- nil,
Hash
,Nucleon::Config
-
data Configurations to evaluate and possibly convert
- nil,
Hash
-
defaults Configuration defaults that may be overridden by config data
- Boolean
-
force Whether or not to force override of values where types don’t match during merge
- Boolean
-
basic_merge Whether or not to perform a basic merge or deep (recursive) merge
-
Returns
Nucleon::Config
-
Returns configuration object
-
Errors
See also:
# File lib/core/config.rb 236 def initialize(data = {}, defaults = {}, force = true, basic_merge = true) 237 @force = force 238 @basic_merge = basic_merge 239 @properties = {} 240 241 if defaults.is_a?(Hash) && ! defaults.empty? 242 defaults = symbol_map(Util::Data.clone(defaults)) 243 end 244 245 case data 246 when Nucleon::Config 247 @properties = Util::Data.merge([ defaults, data.export ], force, basic_merge) 248 when Hash 249 @properties = {} 250 if data.is_a?(Hash) 251 @properties = Util::Data.merge([ defaults, symbol_map(Util::Data.clone(data)) ], force, basic_merge) 252 end 253 else 254 @properties = defaults if defaults.is_a?(Hash) 255 end 256 end
Ensure a data object is a string.
See:
# File lib/core/config.rb 941 def self.string(data, default = '') 942 return Util::Data.string(data, default) 943 end
Return hash as a string map.
This method converts all hash keys to strings. Nested hashes are recursively translated as well.
This comes in really handy when performing operations across hashes in Ruby because of the distinction between symbols and strings.
See:
# File lib/core/config.rb 854 def self.string_map(data) 855 return Util::Data.string_map(data) 856 end
Ensure a data object is a symbol.
See:
# File lib/core/config.rb 959 def self.symbol(data, default = :undefined) 960 return Util::Data.symbol(data, default) 961 end
Return hash as a symbol map.
This method converts all hash keys to symbols. Nested hashes are recursively translated as well.
This comes in really handy when performing operations across hashes in Ruby because of the distinction between symbols and strings.
See:
# File lib/core/config.rb 812 def self.symbol_map(data) 813 return Util::Data.symbol_map(data) 814 end
Test a data object for emptiness and return boolean result.
See:
# File lib/core/config.rb 977 def self.test(data) 978 return Util::Data.test(data) 979 end
Public Instance Methods
Fetch value for key path in the configuration object.
This method is really just to provide an easier interface compatible with Hash
access for simpler configuration groups.
-
Parameters
- String, Symbol
-
name Key to fetch
- ANY
-
default Default value is no value is found for key
- false, Symbol, String
-
format Format to filter final returned value or false for none
-
Returns
- ANY
-
Filtered value for key path from configuration object
-
Errors
See:
# File lib/core/config.rb 459 def [](name, default = nil, format = false) 460 get(name, default, format) 461 end
Set value for key in the configuration object.
This method is really just to provide an easier interface compatible with Hash
access for simpler configuration groups.
-
Parameters
- String, Symbol
-
name Key to fetch
- ANY
-
value Value to set for key
-
Returns
- Void
-
Return value thrown away
-
Errors
See:
# File lib/core/config.rb 631 def []=(name, value) 632 set(name, value) 633 end
Append a value for an array key path in the configuration object.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to modify
- ANY
-
value Value to set for key path
-
Returns
Nucleon::Config
-
Returns reference to self for compound operations
-
Errors
See:
See also:
# File lib/core/config.rb 572 def append(keys, value) 573 modify(@properties, symbol_array(array(keys).flatten), value, false) do |key, processed_value, existing| 574 if existing.is_a?(Array) 575 [ existing, processed_value ].flatten 576 else 577 [ processed_value ] 578 end 579 end 580 return self 581 end
Ensure a data object is an array.
See:
# File lib/core/config.rb 913 def array(data, default = [], split_string = false) 914 return self.class.array(data, default, split_string) 915 end
Clear all properties from the configuration object.
-
Parameters
-
Returns
Nucleon::Config
-
Returns reference to self for compound operations
-
Errors
# File lib/core/config.rb 667 def clear 668 @properties = {} 669 return self 670 end
Set default property values in the configuration object if they don’t exist.
If defaults are given as a string or symbol and the configuration object has a lookup method implemented (corl gem) then the defaults will be dynamically looked up and set.
-
Parameters
-
Returns
Nucleon::Config
-
Returns reference to self for compound operations
-
Errors
See:
See also:
# File lib/core/config.rb 780 def defaults(defaults, options = {}) 781 config = Config.new(options).set(:import_type, :default) 782 return import_base(defaults, config) 783 end
Delete key path from the configuration object.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to remove
- ANY
-
default Default value to return if no existing value found
-
Returns
- ANY
-
Returns default or last value removed from configuration object
-
Errors
See:
See also:
# File lib/core/config.rb 652 def delete(keys, default = nil) 653 existing = modify(@properties, symbol_array(array(keys).flatten), nil, true) 654 return existing[:value] unless existing[:value].nil? 655 return default 656 end
Check whether or not this configuration object is empty.
-
Parameters
-
Returns
- Boolean
-
Whether or not configuration object is empty
-
Errors
# File lib/core/config.rb 270 def empty? 271 @properties.empty? 272 end
Export properties into a regular hash object (cloned)
-
Parameters
-
Returns
Hash
-
Returns a hash of all the configuration properties
-
Errors
# File lib/core/config.rb 794 def export 795 return Util::Data.clone(@properties) 796 end
Run a defined filter on a data object.
See:
# File lib/core/config.rb 893 def filter(data, method = false) 894 return self.class.filter(data, method) 895 end
Fetch value for key path in the configuration object.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to fetch
- ANY
-
default Default value is no value is found for key path
- false, Symbol, String
-
format Format to filter final returned value or false for none
-
Returns
- ANY
-
Filtered value for key path from configuration object
-
Errors
See:
See also:
# File lib/core/config.rb 437 def get(keys, default = nil, format = false) 438 return fetch(@properties, symbol_array(array(keys).flatten), default, format) 439 end
Fetch filtered array value for key path in the configuration object.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to fetch
- Array
-
default Default value is no value is found for key path
-
Returns
- Array
-
Filtered array value for key path from configuration object
-
Errors
See:
See also:
# File lib/core/config.rb 481 def get_array(keys, default = []) 482 return get(keys, default, :array) 483 end
Fetch filtered hash value for key path in the configuration object.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to fetch
Hash
-
default Default hash value is no value is found for key path
-
Returns
Hash
-
Filtered hash value for key path from configuration object
-
Errors
See:
See also:
# File lib/core/config.rb 503 def get_hash(keys, default = {}) 504 return get(keys, default, :hash) 505 end
Check whether or not this configuration object has a specific key.
The purpose of this method is to provide a complimentary has_key? method to the Hash
class so we can check either interchangeably.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to check
-
Returns
- Boolean
-
Whether or not configuration object has a specific key
-
Errors
See:
# File lib/core/config.rb 290 def has_key?(keys) 291 get(keys).nil? ? false : true 292 end
Ensure a data object is a hash
See:
# File lib/core/config.rb 932 def hash(data, default = {}) 933 return self.class.hash(data, default) 934 end
Import new property values into the configuration object. (override)
If properties are given as a string or symbol and the configuration object has a lookup method implemented (corl gem) then the properties will be dynamically looked up and imported.
-
Parameters
-
Returns
Nucleon::Config
-
Returns reference to self for compound operations
-
Errors
See:
# File lib/core/config.rb 754 def import(properties, options = {}) 755 return import_base(properties, options) 756 end
Initialize value for key path in the configuration object if one does not exist yet.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to modify
- ANY
-
default Default value to set for key path if it does not exist yet
-
Returns
Nucleon::Config
-
Returns reference to self for compound operations
-
Errors
See:
# File lib/core/config.rb 523 def init(keys, default = nil) 524 return set(keys, get(keys, default)) 525 end
Return all of the keys for the configuration properties hash.
The purpose of this method is to provide a complimentary keys method to the Hash
class so we can return either interchangeably.
-
Parameters
-
Returns
- Array<Symbol>
-
Array of existing configuration properties
-
Errors
# File lib/core/config.rb 309 def keys 310 @properties.keys 311 end
Prepend a value to an array key path in the configuration object.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to modify
- ANY
-
value Value to set for key path
- Boolean
-
reverse Whether or not to reverse any input value arrays given before prepending
-
Returns
Nucleon::Config
-
Returns reference to self for compound operations
-
Errors
See:
See also:
# File lib/core/config.rb 601 def prepend(keys, value, reverse = false) 602 modify(@properties, symbol_array(array(keys).flatten), value, false) do |key, processed_value, existing| 603 processed_value = processed_value.reverse if reverse && processed_value.is_a?(Array) 604 605 if existing.is_a?(Array) 606 [ processed_value, existing ].flatten 607 else 608 [ processed_value ] 609 end 610 end 611 return self 612 end
Set value for key path in the configuration object.
-
Parameters
- Array<String, Symbol>, String, Symbol
-
keys Key path to modify
- ANY
-
value Value to set for key path
- Boolean
-
delete_nil Delete nil value (serves as an internal way to delete properties)
-
Returns
Nucleon::Config
-
Returns reference to self for compound operations
-
Errors
-
Yields
- Symbol
-
key Configuration key to modify
- ANY
-
value New value of configuration key
- ANY
-
existing Existing value being replaced for the configuration key
See:
See also:
# File lib/core/config.rb 550 def set(keys, value, delete_nil = false, &code) # :yields: key, value, existing 551 modify(@properties, symbol_array(array(keys).flatten), value, delete_nil, &code) 552 return self 553 end
Ensure a data object is a string.
See:
# File lib/core/config.rb 950 def string(data, default = '') 951 return self.class.string(data, default) 952 end
Return hash as a string map.
See:
# File lib/core/config.rb 863 def string_map(data) 864 return self.class.string_map(data) 865 end
Ensure a data object is a symbol.
See:
# File lib/core/config.rb 968 def symbol(data, default = :undefined) 969 return self.class.symbol(data, default) 970 end
Return a symbolized array
-
Parameters
- Array<String, Symbol>
-
array Array of strings or symbols
-
Returns
- Array<Symbol>
-
Returns array of symbols
-
Errors
# File lib/core/config.rb 835 def symbol_array(array) 836 result = [] 837 array.each do |item| 838 result << item.to_sym unless item.nil? 839 end 840 result 841 end
Return hash as a symbol map.
See:
# File lib/core/config.rb 821 def symbol_map(data) 822 return self.class.symbol_map(data) 823 end
Test a data object for emptiness and return boolean result.
See:
# File lib/core/config.rb 986 def test(data) 987 return self.class.test(data) 988 end
Protected Instance Methods
Recursively fetch value for key path in the configuration object.
This method serves as a base accessor to the properties that are defined in the central property collection. It is used and built upon by other accessors defined in the class.
Hash
data is assumed to already be symbolized.
-
Parameters
Hash
-
data Configuration property data
- Array<String, Symbol>, String, Symbol
-
keys Key path to fetch
- ANY
-
default Default value is no value is found for key path
- false, Symbol, String
-
format Format to filter final returned value or false for none
-
Returns
- ANY
-
Filtered value for key path from configuration object
-
Errors
See:
# File lib/core/config.rb 336 def fetch(data, keys, default = nil, format = false) 337 if keys.is_a?(String) || keys.is_a?(Symbol) 338 keys = [ keys ] 339 end 340 341 keys = keys.flatten.compact 342 key = keys.shift 343 344 if data.has_key?(key) 345 value = data[key] 346 347 if keys.empty? 348 return filter(value, format) 349 else 350 return fetch(data[key], keys, default, format) if data[key].is_a?(Hash) 351 end 352 end 353 return filter(default, format) 354 end
Base import method for the configuration object.
This method is used to perform merge overrides of new property values and to set defaults if no properties currently exist.
If properties are given as a string or symbol and the configuration object has a lookup method implemented (corl gem) then the properties will be dynamically looked up and imported.
-
Parameters
-
Returns
Nucleon::Config
-
Returns reference to self for compound operations
-
Errors
See also:
# File lib/core/config.rb 703 def import_base(properties, options = {}) 704 config = Config.new(options, { :force => @force, :basic => @basic_merge }).set(:context, :hash) 705 import_type = config.get(:import_type, :override) 706 707 properties = properties.export if properties.is_a?(Nucleon::Config) 708 709 case properties 710 when Hash 711 data = [ @properties, symbol_map(Util::Data.clone(properties)) ] 712 data = data.reverse if import_type != :override 713 714 @properties = Util::Data.merge(data, config) 715 716 when String, Symbol 717 if respond_to?(:lookup) 718 properties = self.class.lookup(properties.to_s, {}, config) 719 720 data = [ @properties, symbol_map(properties) ] 721 data = data.reverse if import_type != :override 722 723 @properties = Util::Data.merge(data, config) 724 end 725 726 when Array 727 Util::Data.clone(properties).each do |item| 728 import_base(item, config) 729 end 730 end 731 732 return self 733 end
Modify value for key path in the configuration object.
This method serves as a base modifier to the properties that are defined in the central property collection. It is used and built upon by other modifiers defined in the class.
Hash
data is assumed to already be symbolized.
-
Parameters
Hash
-
data Configuration property data
- Array<String, Symbol>, String, Symbol
-
keys Key path to modify
- ANY
-
value Value to set for key path
- Boolean
-
delete_nil Delete nil value (serves as an internal way to delete properties)
-
Returns
- ANY
-
Existing value for key path from configuration object (before update)
-
Errors
-
Yields
- Symbol
-
key Configuration key to modify
- ANY
-
value New value of configuration key
- ANY
-
existing Existing value being replaced for the configuration key
See:
# File lib/core/config.rb 385 def modify(data, keys, value = nil, delete_nil = false, &block) # :yields: key, value, existing 386 if keys.is_a?(String) || keys.is_a?(Symbol) 387 keys = [ keys ] 388 end 389 390 keys = keys.flatten.compact 391 key = keys.shift 392 has_key = data.has_key?(key) 393 existing = { 394 :key => key, 395 :value => ( has_key ? data[key] : nil ) 396 } 397 398 if keys.empty? 399 if value.nil? && delete_nil 400 data.delete(key) if has_key 401 else 402 value = symbol_map(value) if value.is_a?(Hash) 403 data[key] = block ? block.call(key, value, existing[:value]) : value 404 end 405 else 406 data[key] = {} unless has_key 407 408 if data[key].is_a?(Hash) 409 existing = modify(data[key], keys, value, delete_nil, &block) 410 else 411 existing[:value] = nil 412 end 413 end 414 415 return existing 416 end