class Dry::Configurable::Config
Config
exposes setting values through a convenient API
@api public
Attributes
@api private
@api private
@api private
Public Class Methods
@api private
# File lib/dry/configurable/config.rb, line 24 def initialize(settings, values: {}) @_settings = settings @_values = values @_configured = Set.new end
Public Instance Methods
Get config value by a key
@param [String,Symbol] name
@return Config
value
# File lib/dry/configurable/config.rb, line 47 def [](name) name = name.to_sym unless (setting = _settings[name]) raise ArgumentError, "+#{name}+ is not a setting name" end _values.fetch(name) { # Mutable settings may be configured after read _configured.add(name) if setting.cloneable? setting.to_value.tap { |value| _values[name] = value } } end
Set config value. Note that finalized configs cannot be changed.
@param [String,Symbol] name @param [Object] value
# File lib/dry/configurable/config.rb, line 69 def []=(name, value) raise FrozenConfigError, "Cannot modify frozen config" if frozen? name = name.to_sym unless (setting = _settings[name]) raise ArgumentError, "+#{name}+ is not a setting name" end _configured.add(name) _values[name] = setting.constructor.(value) end
Returns true if the value for the given key has been set on this config.
For simple values, this returns true if the value has been explicitly assigned.
For cloneable (mutable) values, since these are captured on read, returns true if the value does not compare equally to its corresdponing default value. This relies on these objects having functioning ‘#==` checks.
@return [Bool]
@api public
# File lib/dry/configurable/config.rb, line 116 def configured?(key) if _configured.include?(key) && _settings[key].cloneable? return _values[key] != _settings[key].to_value end _configured.include?(key) end
@api private
# File lib/dry/configurable/config.rb, line 38 def dup_for_settings(settings) dup.tap { |config| config.instance_variable_set(:@_settings, settings) } end
@api public
# File lib/dry/configurable/config.rb, line 159 def finalize!(freeze_values: false) return self if frozen? values.each_value do |value| if value.is_a?(self.class) value.finalize!(freeze_values: freeze_values) elsif freeze_values value.freeze end end # Memoize the hash for the object when finalizing (regardless of whether values themselves # are to be frozen; the intention of finalization is that no further changes should be # made). The benefit of freezing the hash at this point is that it saves repeated expensive # computation (through Dry::Equalizer's hash implementation) if that hash is to be used # later in performance-sensitive situations, such as when serving as a cache key or similar. @__hash__ = _dry_equalizer_hash freeze end
@api public
# File lib/dry/configurable/config.rb, line 152 def hash return @__hash__ if instance_variable_defined?(:@__hash__) _dry_equalizer_hash end
@api private
# File lib/dry/configurable/config.rb, line 181 def pristine self.class.new(_settings) end
Returns config values as a hash, with nested values also converted from {Config} instances into hashes.
@return [Hash]
@api public
# File lib/dry/configurable/config.rb, line 144 def to_h values.to_h { |key, value| [key, value.is_a?(self.class) ? value.to_h : value] } end
Update config with new values
@param values [Hash, to_hash] A hash with new values
@return [Config]
@api public
# File lib/dry/configurable/config.rb, line 90 def update(values) values.each do |key, value| if self[key].is_a?(self.class) unless value.respond_to?(:to_hash) raise ArgumentError, "#{value.inspect} is not a valid setting value" end self[key].update(value.to_hash) else self[key] = value end end self end
Returns the current config values.
Nested configs remain in their {Config} instances.
@return [Hash]
@api public
# File lib/dry/configurable/config.rb, line 131 def values # Ensure all settings are represented in values _settings.each { |setting| self[setting.name] unless _values.key?(setting.name) } _values end
Private Instance Methods
# File lib/dry/configurable/config.rb, line 208 def dup_values _values.each_with_object({}) { |(key, val), dup_hsh| dup_hsh[key] = _settings[key].cloneable? ? val.dup : val } end
@api private
# File lib/dry/configurable/config.rb, line 31 def initialize_copy(source) super @_values = source.__send__(:dup_values) @_configured = source._configured.dup end
# File lib/dry/configurable/config.rb, line 187 def method_missing(name, *args) setting_name = setting_name_from_method(name) setting = _settings[setting_name] super unless setting if name.end_with?("=") self[setting_name] = args[0] else self[setting_name] end end
# File lib/dry/configurable/config.rb, line 200 def respond_to_missing?(meth, include_private = false) _settings.key?(setting_name_from_method(meth)) || super end
# File lib/dry/configurable/config.rb, line 204 def setting_name_from_method(method_name) method_name.to_s.tr("=", "").to_sym end