Class: Dry::Configurable::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/dry/configurable/config.rb

Overview

Config exposes setting values through a convenient API

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(settings, values: {}) ⇒ Config

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Config.



24
25
26
27
28
# File 'lib/dry/configurable/config.rb', line 24

def initialize(settings, values: {})
  @_settings = settings
  @_values = values
  @_configured = Set.new
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object (private)



187
188
189
190
191
192
193
194
195
196
197
198
# 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

Instance Attribute Details

#_settingsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



14
15
16
# File 'lib/dry/configurable/config.rb', line 14

def _settings
  @_settings
end

#_valuesObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



17
18
19
# File 'lib/dry/configurable/config.rb', line 17

def _values
  @_values
end

Instance Method Details

#[](name) ⇒ Object

Get config value by a key

Parameters:

  • name (String, Symbol)

Returns:

  • Config value



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 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

#[]=(name, value) ⇒ Object

Set config value. Note that finalized configs cannot be changed.

Parameters:

  • name (String, Symbol)
  • value (Object)

Raises:



69
70
71
72
73
74
75
76
77
78
79
80
81
# 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

#_dry_equalizer_hashObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



149
# File 'lib/dry/configurable/config.rb', line 149

alias_method :_dry_equalizer_hash, :hash

#configured?(key) ⇒ Bool

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.

Returns:

  • (Bool)


116
117
118
119
120
121
122
# 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

#dup_for_settings(settings) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



38
39
40
# File 'lib/dry/configurable/config.rb', line 38

def dup_for_settings(settings)
  dup.tap { |config| config.instance_variable_set(:@_settings, settings) }
end

#finalize!(freeze_values: false) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# 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

#hashObject



152
153
154
155
156
# File 'lib/dry/configurable/config.rb', line 152

def hash
  return @__hash__ if instance_variable_defined?(:@__hash__)

  _dry_equalizer_hash
end

#pristineObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



181
182
183
# File 'lib/dry/configurable/config.rb', line 181

def pristine
  self.class.new(_settings)
end

#to_hHash

Returns config values as a hash, with nested values also converted from Dry::Configurable::Config instances into hashes.

Returns:

  • (Hash)


144
145
146
# 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(values) ⇒ Config

Update config with new values

Parameters:

  • values (Hash, #to_hash)

    A hash with new values

Returns:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# 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

#valuesHash

Returns the current config values.

Nested configs remain in their Dry::Configurable::Config instances.

Returns:

  • (Hash)


131
132
133
134
135
136
# 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