dry-configurable 0.16.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/dry-configurable.gemspec +1 -1
- data/lib/dry/configurable/class_methods.rb +5 -14
- data/lib/dry/configurable/config.rb +46 -16
- data/lib/dry/configurable/constants.rb +0 -2
- data/lib/dry/configurable/dsl.rb +0 -2
- data/lib/dry/configurable/errors.rb +3 -2
- data/lib/dry/configurable/extension.rb +1 -1
- data/lib/dry/configurable/instance_methods.rb +1 -1
- data/lib/dry/configurable/methods.rb +1 -1
- data/lib/dry/configurable/setting.rb +23 -17
- data/lib/dry/configurable/settings.rb +22 -13
- data/lib/dry/configurable/version.rb +1 -1
- data/lib/dry/configurable.rb +1 -1
- metadata +14 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d067b9cb78be3e3904b22ab5e73a6903cecb387c241d08c875f2a1eaf1002a4
|
4
|
+
data.tar.gz: c7f9be3367d11ea23c10a8a73d0a63d0fab54a1cf6cd2f5053e8845b808bd801
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45d5b855ac62fa249080b1c40ed9faf0644cf9daa3d3a18c8c3cc0780723006dd510d3b0cb156d2251962775f95396b591e96136d951e08e4679dd684118601d
|
7
|
+
data.tar.gz: fc7420686647324a2c671f183aff7b1fc69131f80db292d0847e53dc5744e16904f56dc74a35b6dadb6cce1f4927409a632d026d7127ccb5844d9b8ba67b4e98
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
<!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
|
2
2
|
|
3
|
+
## 0.16.1 2022-10-13
|
4
|
+
|
5
|
+
|
6
|
+
### Changed
|
7
|
+
|
8
|
+
- Restored performance of config value reads (direct reader methods as well as aggregate methods like `#values` and `#to_h`) to pre-0.16.0 levels (#149 by @timriley)
|
9
|
+
|
10
|
+
[Compare v0.16.0...v0.16.1](https://github.com/dry-rb/dry-configurable/compare/v0.16.0...v0.16.1)
|
11
|
+
|
3
12
|
## 0.16.0 2022-10-08
|
4
13
|
|
5
14
|
|
data/dry-configurable.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.required_ruby_version = ">= 2.7.0"
|
30
30
|
|
31
31
|
# to update dependencies edit project.yml
|
32
|
-
spec.add_runtime_dependency "dry-core", "~> 0
|
32
|
+
spec.add_runtime_dependency "dry-core", "~> 1.0", "< 2"
|
33
33
|
spec.add_runtime_dependency "zeitwerk", "~> 2.6"
|
34
34
|
|
35
35
|
spec.add_development_dependency "bundler"
|
@@ -13,7 +13,7 @@ module Dry
|
|
13
13
|
|
14
14
|
subclass.instance_variable_set(:@__config_extension__, __config_extension__)
|
15
15
|
|
16
|
-
new_settings =
|
16
|
+
new_settings = settings.dup
|
17
17
|
subclass.instance_variable_set(:@_settings, new_settings)
|
18
18
|
|
19
19
|
# Only classes **extending** Dry::Configurable have class-level config. When
|
@@ -43,28 +43,19 @@ module Dry
|
|
43
43
|
def setting(*args, **options, &block)
|
44
44
|
setting = __config_dsl__.setting(*args, **options, &block)
|
45
45
|
|
46
|
-
|
46
|
+
settings << setting
|
47
47
|
|
48
48
|
__config_reader__.define(setting.name) if setting.reader?
|
49
49
|
|
50
50
|
self
|
51
51
|
end
|
52
52
|
|
53
|
-
#
|
54
|
-
#
|
55
|
-
# @return [Set<Symbol>]
|
56
|
-
#
|
57
|
-
# @api public
|
58
|
-
def settings
|
59
|
-
Set[*_settings.map(&:name)]
|
60
|
-
end
|
61
|
-
|
62
|
-
# Return declared settings
|
53
|
+
# Returns the defined settings for the class.
|
63
54
|
#
|
64
55
|
# @return [Settings]
|
65
56
|
#
|
66
57
|
# @api public
|
67
|
-
def
|
58
|
+
def settings
|
68
59
|
@_settings ||= Settings.new
|
69
60
|
end
|
70
61
|
|
@@ -78,7 +69,7 @@ module Dry
|
|
78
69
|
end
|
79
70
|
|
80
71
|
# @api private
|
81
|
-
def __config_build__(settings =
|
72
|
+
def __config_build__(settings = self.settings)
|
82
73
|
__config_extension__.config_class.new(settings)
|
83
74
|
end
|
84
75
|
|
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
|
5
|
-
require "dry/core/equalizer"
|
3
|
+
require "set"
|
6
4
|
|
7
5
|
module Dry
|
8
6
|
module Configurable
|
@@ -18,15 +16,27 @@ module Dry
|
|
18
16
|
# @api private
|
19
17
|
attr_reader :_values
|
20
18
|
|
19
|
+
# @api private
|
20
|
+
attr_reader :_configured
|
21
|
+
protected :_configured
|
22
|
+
|
21
23
|
# @api private
|
22
24
|
def initialize(settings, values: {})
|
23
25
|
@_settings = settings
|
24
26
|
@_values = values
|
27
|
+
@_configured = Set.new
|
28
|
+
end
|
29
|
+
|
30
|
+
# @api private
|
31
|
+
private def initialize_copy(source)
|
32
|
+
super
|
33
|
+
@_values = source.__send__(:dup_values)
|
34
|
+
@_configured = source._configured.dup
|
25
35
|
end
|
26
36
|
|
27
37
|
# @api private
|
28
38
|
def dup_for_settings(settings)
|
29
|
-
|
39
|
+
dup.tap { |config| config.instance_variable_set(:@_settings, settings) }
|
30
40
|
end
|
31
41
|
|
32
42
|
# Get config value by a key
|
@@ -42,10 +52,11 @@ module Dry
|
|
42
52
|
end
|
43
53
|
|
44
54
|
_values.fetch(name) {
|
45
|
-
#
|
46
|
-
|
55
|
+
# Mutable settings may be configured after read
|
56
|
+
_configured.add(name) if setting.cloneable?
|
57
|
+
|
47
58
|
setting.to_value.tap { |value|
|
48
|
-
_values[name] = value
|
59
|
+
_values[name] = value
|
49
60
|
}
|
50
61
|
}
|
51
62
|
end
|
@@ -56,7 +67,7 @@ module Dry
|
|
56
67
|
# @param [String,Symbol] name
|
57
68
|
# @param [Object] value
|
58
69
|
def []=(name, value)
|
59
|
-
raise
|
70
|
+
raise FrozenConfigError, "Cannot modify frozen config" if frozen?
|
60
71
|
|
61
72
|
name = name.to_sym
|
62
73
|
|
@@ -64,6 +75,8 @@ module Dry
|
|
64
75
|
raise ArgumentError, "+#{name}+ is not a setting name"
|
65
76
|
end
|
66
77
|
|
78
|
+
_configured.add(name)
|
79
|
+
|
67
80
|
_values[name] = setting.constructor.(value)
|
68
81
|
end
|
69
82
|
|
@@ -101,11 +114,11 @@ module Dry
|
|
101
114
|
#
|
102
115
|
# @api public
|
103
116
|
def configured?(key)
|
104
|
-
if _settings[key].cloneable?
|
117
|
+
if _configured.include?(key) && _settings[key].cloneable?
|
105
118
|
return _values[key] != _settings[key].to_value
|
106
119
|
end
|
107
120
|
|
108
|
-
|
121
|
+
_configured.include?(key)
|
109
122
|
end
|
110
123
|
|
111
124
|
# Returns the current config values.
|
@@ -116,7 +129,10 @@ module Dry
|
|
116
129
|
#
|
117
130
|
# @api public
|
118
131
|
def values
|
119
|
-
|
132
|
+
# Ensure all settings are represented in values
|
133
|
+
_settings.each { |setting| self[setting.name] unless _values.key?(setting.name) }
|
134
|
+
|
135
|
+
_values
|
120
136
|
end
|
121
137
|
|
122
138
|
# Returns config values as a hash, with nested values also converted from {Config} instances
|
@@ -130,7 +146,19 @@ module Dry
|
|
130
146
|
end
|
131
147
|
|
132
148
|
# @api private
|
149
|
+
alias_method :_dry_equalizer_hash, :hash
|
150
|
+
|
151
|
+
# @api public
|
152
|
+
def hash
|
153
|
+
return @__hash__ if instance_variable_defined?(:@__hash__)
|
154
|
+
|
155
|
+
_dry_equalizer_hash
|
156
|
+
end
|
157
|
+
|
158
|
+
# @api public
|
133
159
|
def finalize!(freeze_values: false)
|
160
|
+
return self if frozen?
|
161
|
+
|
134
162
|
values.each_value do |value|
|
135
163
|
if value.is_a?(self.class)
|
136
164
|
value.finalize!(freeze_values: freeze_values)
|
@@ -139,6 +167,13 @@ module Dry
|
|
139
167
|
end
|
140
168
|
end
|
141
169
|
|
170
|
+
# Memoize the hash for the object when finalizing (regardless of whether values themselves
|
171
|
+
# are to be frozen; the intention of finalization is that no further changes should be
|
172
|
+
# made). The benefit of freezing the hash at this point is that it saves repeated expensive
|
173
|
+
# computation (through Dry::Equalizer's hash implementation) if that hash is to be used
|
174
|
+
# later in performance-sensitive situations, such as when serving as a cache key or similar.
|
175
|
+
@__hash__ = _dry_equalizer_hash
|
176
|
+
|
142
177
|
freeze
|
143
178
|
end
|
144
179
|
|
@@ -175,11 +210,6 @@ module Dry
|
|
175
210
|
dup_hsh[key] = _settings[key].cloneable? ? val.dup : val
|
176
211
|
}
|
177
212
|
end
|
178
|
-
|
179
|
-
def initialize_copy(source)
|
180
|
-
super
|
181
|
-
@_values = source.__send__(:dup_values)
|
182
|
-
end
|
183
213
|
end
|
184
214
|
end
|
185
215
|
end
|
data/lib/dry/configurable/dsl.rb
CHANGED
@@ -2,40 +2,41 @@
|
|
2
2
|
|
3
3
|
require "set"
|
4
4
|
|
5
|
-
require "dry/core/equalizer"
|
6
|
-
|
7
5
|
module Dry
|
8
6
|
module Configurable
|
9
|
-
#
|
7
|
+
# A defined setting.
|
10
8
|
#
|
11
|
-
# @api
|
9
|
+
# @api public
|
12
10
|
class Setting
|
13
11
|
include Dry::Equalizer(:name, :default, :constructor, :children, :options, inspect: false)
|
14
12
|
|
15
|
-
OPTIONS = %i[default reader constructor cloneable settings config_class].freeze
|
13
|
+
OPTIONS = %i[default reader constructor mutable cloneable settings config_class].freeze
|
16
14
|
|
17
15
|
DEFAULT_CONSTRUCTOR = -> v { v }.freeze
|
18
16
|
|
19
|
-
|
17
|
+
MUTABLE_VALUE_TYPES = [Array, Hash, Set, Config].freeze
|
20
18
|
|
21
|
-
# @api
|
19
|
+
# @api public
|
22
20
|
attr_reader :name
|
23
21
|
|
24
|
-
# @api
|
22
|
+
# @api public
|
25
23
|
attr_reader :default
|
26
24
|
|
27
|
-
# @api
|
25
|
+
# @api public
|
26
|
+
attr_reader :mutable
|
27
|
+
|
28
|
+
# @api public
|
28
29
|
attr_reader :constructor
|
29
30
|
|
30
|
-
# @api
|
31
|
+
# @api public
|
31
32
|
attr_reader :children
|
32
33
|
|
33
|
-
# @api
|
34
|
+
# @api public
|
34
35
|
attr_reader :options
|
35
36
|
|
36
37
|
# @api private
|
37
|
-
def self.
|
38
|
-
|
38
|
+
def self.mutable_value?(value)
|
39
|
+
MUTABLE_VALUE_TYPES.any? { |type| value.is_a?(type) }
|
39
40
|
end
|
40
41
|
|
41
42
|
# @api private
|
@@ -48,6 +49,10 @@ module Dry
|
|
48
49
|
)
|
49
50
|
@name = name
|
50
51
|
@default = default
|
52
|
+
@mutable = children.any? || options.fetch(:mutable) {
|
53
|
+
# Allow `cloneable` as an option alias for `mutable`
|
54
|
+
options.fetch(:cloneable) { Setting.mutable_value?(default) }
|
55
|
+
}
|
51
56
|
@constructor = constructor
|
52
57
|
@children = children
|
53
58
|
@options = options
|
@@ -58,10 +63,11 @@ module Dry
|
|
58
63
|
options[:reader].equal?(true)
|
59
64
|
end
|
60
65
|
|
61
|
-
# @api
|
62
|
-
def
|
63
|
-
|
66
|
+
# @api public
|
67
|
+
def mutable?
|
68
|
+
mutable
|
64
69
|
end
|
70
|
+
alias_method :cloneable?, :mutable?
|
65
71
|
|
66
72
|
# @api private
|
67
73
|
def to_value
|
@@ -71,7 +77,7 @@ module Dry
|
|
71
77
|
value = default
|
72
78
|
value = constructor.(value) unless value.eql?(Undefined)
|
73
79
|
|
74
|
-
|
80
|
+
mutable? ? value.dup : value
|
75
81
|
end
|
76
82
|
end
|
77
83
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/equalizer"
|
4
|
-
|
5
3
|
module Dry
|
6
4
|
module Configurable
|
7
|
-
# A settings
|
5
|
+
# A collection of defined settings on a given class.
|
8
6
|
#
|
9
7
|
# @api private
|
10
8
|
class Settings
|
@@ -20,37 +18,48 @@ module Dry
|
|
20
18
|
@settings = settings.each_with_object({}) { |s, m| m[s.name] = s }
|
21
19
|
end
|
22
20
|
|
21
|
+
# @api private
|
22
|
+
private def initialize_copy(source)
|
23
|
+
@settings = source.settings.dup
|
24
|
+
end
|
25
|
+
|
23
26
|
# @api private
|
24
27
|
def <<(setting)
|
25
28
|
settings[setting.name] = setting
|
26
29
|
self
|
27
30
|
end
|
28
31
|
|
29
|
-
#
|
32
|
+
# Returns the setting for the given name, if found.
|
33
|
+
#
|
34
|
+
# @return [Setting, nil] the setting, or nil if not found
|
35
|
+
#
|
36
|
+
# @api public
|
30
37
|
def [](name)
|
31
38
|
settings[name]
|
32
39
|
end
|
33
40
|
|
34
|
-
#
|
41
|
+
# Returns true if a setting for the given name is defined.
|
42
|
+
#
|
43
|
+
# @return [Boolean]
|
44
|
+
#
|
45
|
+
# @api public
|
35
46
|
def key?(name)
|
36
47
|
keys.include?(name)
|
37
48
|
end
|
38
49
|
|
39
|
-
#
|
50
|
+
# Returns the list of defined setting names.
|
51
|
+
#
|
52
|
+
# @return [Array<Symbol>]
|
53
|
+
#
|
54
|
+
# @api public
|
40
55
|
def keys
|
41
56
|
settings.keys
|
42
57
|
end
|
43
58
|
|
44
|
-
# @api
|
59
|
+
# @api public
|
45
60
|
def each(&block)
|
46
61
|
settings.each_value(&block)
|
47
62
|
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def initialize_copy(source)
|
52
|
-
@settings = source.settings.dup
|
53
|
-
end
|
54
63
|
end
|
55
64
|
end
|
56
65
|
end
|
data/lib/dry/configurable.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-configurable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Holland
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-core
|
@@ -16,14 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0
|
19
|
+
version: '1.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '2'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - "~>"
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0
|
29
|
+
version: '1.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: zeitwerk
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,7 +120,7 @@ metadata:
|
|
114
120
|
changelog_uri: https://github.com/dry-rb/dry-configurable/blob/main/CHANGELOG.md
|
115
121
|
source_code_uri: https://github.com/dry-rb/dry-configurable
|
116
122
|
bug_tracker_uri: https://github.com/dry-rb/dry-configurable/issues
|
117
|
-
post_install_message:
|
123
|
+
post_install_message:
|
118
124
|
rdoc_options: []
|
119
125
|
require_paths:
|
120
126
|
- lib
|
@@ -129,8 +135,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
129
135
|
- !ruby/object:Gem::Version
|
130
136
|
version: '0'
|
131
137
|
requirements: []
|
132
|
-
rubygems_version: 3.
|
133
|
-
signing_key:
|
138
|
+
rubygems_version: 3.1.6
|
139
|
+
signing_key:
|
134
140
|
specification_version: 4
|
135
141
|
summary: A mixin to add configuration functionality to your classes
|
136
142
|
test_files: []
|