dry-initializer 3.0.1
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 +7 -0
- data/.codeclimate.yml +23 -0
- data/.gitignore +10 -0
- data/.rspec +4 -0
- data/.rubocop.yml +51 -0
- data/.travis.yml +28 -0
- data/CHANGELOG.md +883 -0
- data/Gemfile +29 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +90 -0
- data/Rakefile +8 -0
- data/benchmarks/compare_several_defaults.rb +82 -0
- data/benchmarks/plain_options.rb +63 -0
- data/benchmarks/plain_params.rb +84 -0
- data/benchmarks/with_coercion.rb +71 -0
- data/benchmarks/with_defaults.rb +66 -0
- data/benchmarks/with_defaults_and_coercion.rb +59 -0
- data/dry-initializer.gemspec +20 -0
- data/lib/dry-initializer.rb +1 -0
- data/lib/dry/initializer.rb +61 -0
- data/lib/dry/initializer/builders.rb +7 -0
- data/lib/dry/initializer/builders/attribute.rb +81 -0
- data/lib/dry/initializer/builders/initializer.rb +61 -0
- data/lib/dry/initializer/builders/reader.rb +50 -0
- data/lib/dry/initializer/builders/signature.rb +32 -0
- data/lib/dry/initializer/config.rb +184 -0
- data/lib/dry/initializer/definition.rb +65 -0
- data/lib/dry/initializer/dispatchers.rb +112 -0
- data/lib/dry/initializer/dispatchers/build_nested_type.rb +59 -0
- data/lib/dry/initializer/dispatchers/check_type.rb +43 -0
- data/lib/dry/initializer/dispatchers/prepare_default.rb +40 -0
- data/lib/dry/initializer/dispatchers/prepare_ivar.rb +12 -0
- data/lib/dry/initializer/dispatchers/prepare_optional.rb +13 -0
- data/lib/dry/initializer/dispatchers/prepare_reader.rb +30 -0
- data/lib/dry/initializer/dispatchers/prepare_source.rb +28 -0
- data/lib/dry/initializer/dispatchers/prepare_target.rb +44 -0
- data/lib/dry/initializer/dispatchers/unwrap_type.rb +22 -0
- data/lib/dry/initializer/dispatchers/wrap_type.rb +27 -0
- data/lib/dry/initializer/dsl.rb +43 -0
- data/lib/dry/initializer/mixin.rb +15 -0
- data/lib/dry/initializer/mixin/local.rb +19 -0
- data/lib/dry/initializer/mixin/root.rb +10 -0
- data/lib/dry/initializer/struct.rb +40 -0
- data/lib/dry/initializer/undefined.rb +2 -0
- data/lib/tasks/benchmark.rake +41 -0
- data/lib/tasks/profile.rake +78 -0
- data/spec/attributes_spec.rb +38 -0
- data/spec/coercion_of_nil_spec.rb +25 -0
- data/spec/custom_dispatchers_spec.rb +35 -0
- data/spec/custom_initializer_spec.rb +30 -0
- data/spec/default_values_spec.rb +83 -0
- data/spec/definition_spec.rb +111 -0
- data/spec/invalid_default_spec.rb +13 -0
- data/spec/list_type_spec.rb +32 -0
- data/spec/missed_default_spec.rb +14 -0
- data/spec/nested_type_spec.rb +44 -0
- data/spec/optional_spec.rb +71 -0
- data/spec/options_tolerance_spec.rb +11 -0
- data/spec/public_attributes_utility_spec.rb +22 -0
- data/spec/reader_spec.rb +87 -0
- data/spec/repetitive_definitions_spec.rb +69 -0
- data/spec/several_assignments_spec.rb +41 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/subclassing_spec.rb +49 -0
- data/spec/type_argument_spec.rb +35 -0
- data/spec/type_constraint_spec.rb +78 -0
- data/spec/value_coercion_via_dry_types_spec.rb +29 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e17a987f9500b55fd7bf3c60caa5e8ce5c4c26cb78b94f339b62a63bdeb5a9e3
|
4
|
+
data.tar.gz: 362138efc7974312bf747f060c7af4d4117e6b8c7648849998c1aefb39d14b1e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc4416e43fce6418f4708f5d7fc6753096009e9f2087f334bc11a2edeb44b3f9099d6d53ad9969d7e38ffefa524031c0e95fd4c7cb277ff7fed1a9ff63ebad5b
|
7
|
+
data.tar.gz: a2745ea32279c9e6bd9a964b0cef5e876bf3f02afd604b4193e6223d629fc1ca6ee8fd22cf1543d652b9ff5548b3bb9a7fc28c7a06f4eeb04cf233b4ccf451de
|
data/.codeclimate.yml
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
engines:
|
3
|
+
rubocop:
|
4
|
+
enabled: true
|
5
|
+
checks:
|
6
|
+
Rubocop/Style/FrozenStringLiteralComment:
|
7
|
+
enabled: false
|
8
|
+
Rubocop/Style/PercentLiteralDelimiters:
|
9
|
+
enabled: false
|
10
|
+
Rubocop/Lint/UnderscorePrefixedVariableName:
|
11
|
+
enabled: false
|
12
|
+
duplication:
|
13
|
+
enabled: true
|
14
|
+
config:
|
15
|
+
languages:
|
16
|
+
- ruby
|
17
|
+
exclude_paths:
|
18
|
+
- "benchmarks/**/*"
|
19
|
+
- "spec/**/*"
|
20
|
+
- "lib/tasks/**/*"
|
21
|
+
ratings:
|
22
|
+
paths:
|
23
|
+
- "lib/**/*"
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
---
|
2
|
+
AllCops:
|
3
|
+
DisplayCopNames: true
|
4
|
+
DisplayStyleGuide: true
|
5
|
+
StyleGuideCopsOnly: true
|
6
|
+
TargetRubyVersion: 2.3
|
7
|
+
Exclude:
|
8
|
+
- lib/tasks/*.rake
|
9
|
+
|
10
|
+
Bundler/DuplicatedGem:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Naming/FileName:
|
14
|
+
Exclude:
|
15
|
+
- lib/dry-initializer.rb
|
16
|
+
|
17
|
+
Style/CaseEquality:
|
18
|
+
Enabled: false
|
19
|
+
|
20
|
+
Style/ClassAndModuleChildren:
|
21
|
+
Enabled: false
|
22
|
+
|
23
|
+
Style/ClassVars:
|
24
|
+
Enabled: false
|
25
|
+
|
26
|
+
Style/Documentation:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Style/DoubleNegation:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/Lambda:
|
33
|
+
Exclude:
|
34
|
+
- spec/**/*.rb
|
35
|
+
|
36
|
+
Style/LambdaCall:
|
37
|
+
Enabled: false
|
38
|
+
|
39
|
+
Style/RescueModifier:
|
40
|
+
Exclude:
|
41
|
+
- spec/**/*.rb
|
42
|
+
|
43
|
+
Style/Semicolon:
|
44
|
+
Exclude:
|
45
|
+
- spec/**/*.rb
|
46
|
+
|
47
|
+
Style/StringLiterals:
|
48
|
+
EnforcedStyle: double_quotes
|
49
|
+
|
50
|
+
Style/StringLiteralsInInterpolation:
|
51
|
+
EnforcedStyle: double_quotes
|
data/.travis.yml
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
language: ruby
|
3
|
+
cache: bundler
|
4
|
+
bundler_args: --without benchmarks tools
|
5
|
+
script:
|
6
|
+
- bundle exec rake spec
|
7
|
+
rvm:
|
8
|
+
- 2.3.8
|
9
|
+
- 2.4.6
|
10
|
+
- 2.5.5
|
11
|
+
- 2.6.2
|
12
|
+
- jruby-9.2.7.0
|
13
|
+
- jruby-9000
|
14
|
+
- rbx-3
|
15
|
+
- ruby-head
|
16
|
+
- truffleruby
|
17
|
+
env:
|
18
|
+
global:
|
19
|
+
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
20
|
+
matrix:
|
21
|
+
allow_failures:
|
22
|
+
- rvm: rbx-3
|
23
|
+
- rvm: ruby-head
|
24
|
+
- rvm: jruby-head
|
25
|
+
- rvm: truffleruby
|
26
|
+
include:
|
27
|
+
- rvm: jruby-head
|
28
|
+
before_install: gem install bundler --no-document
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,883 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
7
|
+
|
8
|
+
## [3.0.1] [2019-04-15]
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
|
12
|
+
- Usage of underscored names of `option`-s and `param`-s (nepalez)
|
13
|
+
|
14
|
+
You can use any sequence of underscores except for in nested types.
|
15
|
+
In nested types single underscores can be used to split alphanumeric
|
16
|
+
parts only.
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
class Test
|
20
|
+
extend Dry::Initializer
|
21
|
+
|
22
|
+
# Proper usage
|
23
|
+
option :foo_bar do
|
24
|
+
option :__foo__, proc(&:to_s)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Improper usage
|
29
|
+
option :__foo__ do
|
30
|
+
# ...
|
31
|
+
end
|
32
|
+
|
33
|
+
option :foo__bar do
|
34
|
+
# ...
|
35
|
+
end
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
This restriction is necessary because we constantize option/param names
|
40
|
+
when defining nested structs.
|
41
|
+
|
42
|
+
## [3.0.0] [2019-04-14]
|
43
|
+
|
44
|
+
### Added
|
45
|
+
|
46
|
+
- Support of wrapped types/coercers (nepalez)
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
class Test
|
50
|
+
# Wrap type to the array
|
51
|
+
param :foo, [proc(&:to_s)]
|
52
|
+
end
|
53
|
+
|
54
|
+
# And the value will be wrapped as well
|
55
|
+
test = Test.new(42)
|
56
|
+
test.foo # => ["42"]
|
57
|
+
```
|
58
|
+
|
59
|
+
- It works with several layers of nesting (nepalez)
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
class Test
|
63
|
+
# Wrap type to the array
|
64
|
+
param :foo, [[proc(&:to_s)]]
|
65
|
+
end
|
66
|
+
|
67
|
+
# And the value will be wrapped as well
|
68
|
+
test = Test.new(42)
|
69
|
+
test.foo # => [["42"]]
|
70
|
+
```
|
71
|
+
|
72
|
+
- Support of nested types/coercers (nepalez)
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
class Test
|
76
|
+
param :foo do
|
77
|
+
option :bar do
|
78
|
+
option :baz, proc(&:to_s)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
test = Test.new(bar: { "baz" => 42 })
|
84
|
+
test.foo.bar.baz # => "42"
|
85
|
+
```
|
86
|
+
|
87
|
+
- Wrapped/nested combinations are supported as well (nepalez)
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
class Test
|
91
|
+
param :foo, [] do
|
92
|
+
option :bar, proc(&:to_s)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
test = Test.new(bar: 42)
|
97
|
+
test.foo.first.bar # => "42"
|
98
|
+
```
|
99
|
+
|
100
|
+
## [2.7.0] Unreleazed
|
101
|
+
|
102
|
+
### Fixed
|
103
|
+
|
104
|
+
- Roll back master to the state of [2.5.0].
|
105
|
+
|
106
|
+
Somehow distinction between `@default_null` and `@null` variables
|
107
|
+
in the `Dry::Initializer::Builders` broken the `rom` library.
|
108
|
+
|
109
|
+
The version [2.6.0] has been yanked on rubygems, so the master
|
110
|
+
was rolled back to the previous state until the reason for
|
111
|
+
the incompatibility become clear (bjeanes, nepalez)
|
112
|
+
|
113
|
+
## [2.6.0] [2018-09-09] (YANKED)
|
114
|
+
|
115
|
+
## [2.5.0] [2018-08-17]
|
116
|
+
|
117
|
+
### Fixed
|
118
|
+
|
119
|
+
- `nil` coercion (belousovAV)
|
120
|
+
|
121
|
+
When default value is `nil` instead of `Dry::Initializer::UNDEFINED`,
|
122
|
+
the coercion should be applied to any value, including `nil`, because
|
123
|
+
we cannot distinct "undefined" `nil` from the "assigned" `nil` value.
|
124
|
+
|
125
|
+
## [2.4.0] [2018-02-01]
|
126
|
+
|
127
|
+
### Added
|
128
|
+
- Dispatchers for adding syntax sugar to `param` and `options` (nepalez)
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
# Converts `integer: true` to `type: proc(&:to_i)`
|
132
|
+
dispatcher = ->(op) { op[:integer] ? op.merge(type: proc(&:to_i)) : op }
|
133
|
+
# Register a dispatcher
|
134
|
+
Dry::Initializer::Dispatchers << dispatcher
|
135
|
+
# Use syntax sugar
|
136
|
+
class User
|
137
|
+
param :id, integer: true # same as param :id, proc(&:to_i)
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
## [2.3.0] [2017-09-19]
|
142
|
+
|
143
|
+
### Added
|
144
|
+
- Type coercer can take second argument for the initialized instance (nepalez)
|
145
|
+
This allows to wrap assigned value to the object that refers back
|
146
|
+
to the initializer instance. More verbose example:
|
147
|
+
|
148
|
+
```ruby
|
149
|
+
class Location < String
|
150
|
+
attr_reader :parameter # refers back to its parameter
|
151
|
+
|
152
|
+
def initialize(name, parameter)
|
153
|
+
super(name)
|
154
|
+
@parameter = parameter
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
class Parameter
|
159
|
+
extend Dry::Initializer
|
160
|
+
param :name
|
161
|
+
param :location, ->(value, param) { Location.new(value, param) }
|
162
|
+
end
|
163
|
+
|
164
|
+
offset = Parameter.new "offset", location: "query"
|
165
|
+
offset.name # => "offset"
|
166
|
+
offset.location # => "query"
|
167
|
+
offset.location.parameter == offset # true
|
168
|
+
```
|
169
|
+
|
170
|
+
## [2.2.0] [2017-09-13]
|
171
|
+
|
172
|
+
### Added
|
173
|
+
- Option `:desc` for option/param to add a description (nepalez)
|
174
|
+
|
175
|
+
- Methods `Definition#inch` and `Config#inch` to inspect definitions (nepalez)
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
class User
|
179
|
+
extend Dry::Initializer
|
180
|
+
option :name, proc(&:to_s), optional: true, desc: "User name"
|
181
|
+
option :email, optional: true, desc: "user email"
|
182
|
+
end
|
183
|
+
|
184
|
+
User.dry_initializer.inch
|
185
|
+
# @!method initialize(*, **options)
|
186
|
+
# Initializes an instance of User
|
187
|
+
# @option [Object] :name (optional) User name
|
188
|
+
# @option [Object] :email (optional) User email
|
189
|
+
# @return [User]
|
190
|
+
```
|
191
|
+
|
192
|
+
## [2.1.0] [2017-09-11]
|
193
|
+
|
194
|
+
### Added
|
195
|
+
- Method `#options` to param/option definition (nepalez)
|
196
|
+
|
197
|
+
```ruby
|
198
|
+
class User
|
199
|
+
extend Dry::Initializer
|
200
|
+
option :name, proc(&:to_s), optional: true
|
201
|
+
option :email, optional: true
|
202
|
+
end
|
203
|
+
|
204
|
+
User.dry_initializer.options.map do |option|
|
205
|
+
[option.source, option.options]
|
206
|
+
end
|
207
|
+
# => [
|
208
|
+
# [:name, { type: proc(&:to_s), as: :name, optional: true }],
|
209
|
+
# [:email, { as: :email, optional: true }]
|
210
|
+
# ]
|
211
|
+
```
|
212
|
+
|
213
|
+
This method can be helpful for replicating params/options
|
214
|
+
in another class without inheritance.
|
215
|
+
|
216
|
+
## [2.0.0] [2017-08-28]
|
217
|
+
|
218
|
+
The gem has been rewritten under the hood keeping its documented
|
219
|
+
interface about the same (see "Deleted" section below for the only
|
220
|
+
backward-incompatible change).
|
221
|
+
|
222
|
+
The main achievement of this version is fixing an edge case where
|
223
|
+
change in params/options of superclass wasn't reflected in its
|
224
|
+
previously declared subclasses.
|
225
|
+
|
226
|
+
Thanks to @solnic for the idea of class-level container,
|
227
|
+
and to @gzigzigzeo for persuading me to do this refactoring.
|
228
|
+
|
229
|
+
### Deleted
|
230
|
+
- Undocumented variable `@__option__` which was the main reason for refactoring
|
231
|
+
(gzigzigzeo, nepalez).
|
232
|
+
|
233
|
+
### Added
|
234
|
+
- Class method `.dry_initializer` -- a container for `.params` and `.options`
|
235
|
+
`.definitions` along with the `.null` setting (either `nil` or `UNDEFINED`)
|
236
|
+
used for unassigned values (nepalez)
|
237
|
+
|
238
|
+
- `.dry_initializer.attributes` method takes an instance of the same class
|
239
|
+
and returns the hash of assigned options. This provide the same
|
240
|
+
functionality as previously used instance variable `@__options__` (nepalez)
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
object.class.dry_initializer.attributes(object)
|
244
|
+
```
|
245
|
+
|
246
|
+
When you use "Dry::Initializer.define -> { ... }" syntax,
|
247
|
+
the class method `.dry_initializer` is not defined. To access attributes
|
248
|
+
you should use private instance method `#__dry_initializer_config__` instead:
|
249
|
+
|
250
|
+
```ruby
|
251
|
+
object.send(:__dry_initializer_config__).attributes(object)
|
252
|
+
```
|
253
|
+
|
254
|
+
Both methods `.dry_initializer` and `#__dry_initializer_config__` refer
|
255
|
+
to the same object.
|
256
|
+
|
257
|
+
- `.dry_initializer.public_attributes`. This method works differently:
|
258
|
+
it looks through (possibly reloaded) readers instead of variables
|
259
|
+
(gzigzigzeo, nepalez)
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
object.class.dry_initializer.public_attributes(object)
|
263
|
+
```
|
264
|
+
|
265
|
+
You can use the same trick as above mutatis mutandis.
|
266
|
+
|
267
|
+
### Fixed
|
268
|
+
- Definition order dependency bug (nepalez)
|
269
|
+
|
270
|
+
I've found out that if you provided a subclass and then changed params
|
271
|
+
or options of its superclass, these changes woudn't be reflected in
|
272
|
+
subclasses until you change any of it params/options as well.
|
273
|
+
|
274
|
+
Now this bug is fixed: every time you call `param` or `option` at
|
275
|
+
any class, the gem scans through all its descendants to the very bottom
|
276
|
+
of the tree, and reloads their defintitions.
|
277
|
+
|
278
|
+
Being done in load time, the rebuilt makes no effect on runtime performance.
|
279
|
+
|
280
|
+
- Possible misbehavior when you define param and option with the same name (nepalez)
|
281
|
+
|
282
|
+
Doing this will provide `option :name` only, not both:
|
283
|
+
|
284
|
+
```ruby
|
285
|
+
param :name
|
286
|
+
option :name
|
287
|
+
```
|
288
|
+
|
289
|
+
- Attempt to redefine param/option of superclass with option/param in
|
290
|
+
its subclass will cause an exception because it would break
|
291
|
+
Liskov substitute principle with unexpected behaviour (nepalez)
|
292
|
+
|
293
|
+
No, you can do neither these definitions, nor vice versa:
|
294
|
+
|
295
|
+
```ruby
|
296
|
+
class Foo
|
297
|
+
extend Dry::Intitializer
|
298
|
+
param :name
|
299
|
+
end
|
300
|
+
|
301
|
+
class Bar < Foo
|
302
|
+
option :name
|
303
|
+
end
|
304
|
+
```
|
305
|
+
|
306
|
+
- When you reloading previously defined param of superclass, the gem
|
307
|
+
will check all its descendands for whether all required positional params
|
308
|
+
goes before optional ones (nepalez)
|
309
|
+
|
310
|
+
```ruby
|
311
|
+
class Foo
|
312
|
+
param :name
|
313
|
+
# Foo: def initializer(name)
|
314
|
+
end
|
315
|
+
|
316
|
+
class Bar
|
317
|
+
param :email
|
318
|
+
# Bar: def initializer(name, email)
|
319
|
+
end
|
320
|
+
|
321
|
+
class Foo
|
322
|
+
# This raises SyntaxError because in Bar this would cause wrong definition
|
323
|
+
# Foo: def initializer(name = nil)
|
324
|
+
# Bar: def initializer(name = nil, email)
|
325
|
+
param :name, optional: true
|
326
|
+
end
|
327
|
+
```
|
328
|
+
|
329
|
+
### Changed
|
330
|
+
- Under the hood I've separated param/option settings declaration (a container
|
331
|
+
with param/option settings) from code builders for initializer and readers
|
332
|
+
(nepalez)
|
333
|
+
|
334
|
+
You can check both the code for the `__initializer__`:
|
335
|
+
|
336
|
+
```ruby
|
337
|
+
class Foo
|
338
|
+
extend Dry::Initializer
|
339
|
+
# ...
|
340
|
+
end
|
341
|
+
|
342
|
+
Foo.dry_initializer.code
|
343
|
+
```
|
344
|
+
|
345
|
+
and readers:
|
346
|
+
|
347
|
+
```ruby
|
348
|
+
Foo.dry_initializer.params.map(&:code)
|
349
|
+
Foo.dry_initializer.options.map(&:code)
|
350
|
+
|
351
|
+
# or
|
352
|
+
|
353
|
+
Foo.dry_initializer.definitions.values.map(&:code)
|
354
|
+
```
|
355
|
+
|
356
|
+
You can also check settings for every param and option using methods
|
357
|
+
`dry_initializer.params`, `dry_initializer.options` (lists), or
|
358
|
+
`dry_initializer.definitions` (hash).
|
359
|
+
|
360
|
+
You can check null value via `.dry_initializer.null` which is different
|
361
|
+
for `Dry::Initializer` and `Dry::Initializer[undefined: false]` modules.
|
362
|
+
|
363
|
+
- Optimized the code for `__initializer__`-s (the method where all magics occurs)
|
364
|
+
(nepalez)
|
365
|
+
|
366
|
+
Benchmarks remained about the same:
|
367
|
+
|
368
|
+
```shell
|
369
|
+
rake benchmark
|
370
|
+
```
|
371
|
+
|
372
|
+
```
|
373
|
+
Benchmark for instantiation with plain params
|
374
|
+
value_struct: 4317196.9 i/s
|
375
|
+
plain Ruby: 4129803.9 i/s - 1.05x slower
|
376
|
+
dry-initializer: 1710702.1 i/s - 2.52x slower
|
377
|
+
concord: 1372630.4 i/s - 3.15x slower
|
378
|
+
values: 601651.8 i/s - 7.18x slower
|
379
|
+
attr_extras: 535599.5 i/s - 8.06x slower
|
380
|
+
```
|
381
|
+
|
382
|
+
```
|
383
|
+
Benchmark for instantiation with plain options
|
384
|
+
plain Ruby: 1769174.1 i/s
|
385
|
+
dry-initializer: 636634.1 i/s - 2.78x slower
|
386
|
+
kwattr: 423296.5 i/s - 4.18x slower
|
387
|
+
anima: 399415.0 i/s - 4.43x slower
|
388
|
+
```
|
389
|
+
|
390
|
+
```
|
391
|
+
Benchmark for instantiation with coercion
|
392
|
+
plain Ruby: 1565501.0 i/s
|
393
|
+
fast_attributes: 569952.9 i/s - 2.75x slower
|
394
|
+
dry-initializer: 461122.1 i/s - 3.39x slower
|
395
|
+
virtus: 138074.8 i/s - 11.34x slower
|
396
|
+
```
|
397
|
+
|
398
|
+
```
|
399
|
+
Benchmark for instantiation with default values
|
400
|
+
plain Ruby: 3402455.4 i/s
|
401
|
+
kwattr: 586206.5 i/s - 5.80x slower
|
402
|
+
dry-initializer: 528482.2 i/s - 6.44x slower
|
403
|
+
active_attr: 298697.7 i/s - 11.39x slower
|
404
|
+
```
|
405
|
+
|
406
|
+
```
|
407
|
+
Benchmark for instantiation with type constraints and default values
|
408
|
+
plain Ruby: 2881696.1 i/s
|
409
|
+
dry-initializer: 470815.1 i/s - 6.12x slower
|
410
|
+
virtus: 180272.6 i/s - 15.99x slower
|
411
|
+
```
|
412
|
+
|
413
|
+
## [1.4.1] [2017-04-05]
|
414
|
+
|
415
|
+
### Fixed
|
416
|
+
- Warning about redefined `#initialize` in case the method reloaded in a klass
|
417
|
+
that extends the module (nepalez, sergey-chechaev)
|
418
|
+
|
419
|
+
### Changed
|
420
|
+
- Rename `Dry::Initializer::DSL` -> `Dry::Initializer::ClassDSL` (nepalez)
|
421
|
+
- Add `Dry::Initializer::InstanceDSL` (nepalez)
|
422
|
+
|
423
|
+
### Deprecated
|
424
|
+
- `Dry::Initializer::Mixin`. In latest version this was an alias for
|
425
|
+
`Dry::Initializer` that kept for backward compatibility for early versions of the gem.
|
426
|
+
|
427
|
+
This story will come to the end in `v2.1.0`.
|
428
|
+
|
429
|
+
## [1.4.0] [2017-03-08]
|
430
|
+
|
431
|
+
### Changed (backward-incompatible)
|
432
|
+
- The `@__options__` hash now collects all assigned attributes,
|
433
|
+
collected via `#option` (as before), and `#param` (nepalez)
|
434
|
+
|
435
|
+
## [1.3.0] [2017-03-05]
|
436
|
+
|
437
|
+
### Added
|
438
|
+
- No-undefined configuration of the initializer (nepalez, flash-gordon)
|
439
|
+
|
440
|
+
You can either extend or include module `Dry::Initializer` with additional option
|
441
|
+
`[undefined: false]`. This time `nil` will be assigned instead of
|
442
|
+
`Dry::Initializer::UNDEFINED`. Readers becomes faster because there is no need
|
443
|
+
to chech whether a variable was defined or not. At the same time the initializer
|
444
|
+
doesn't distinct cases when a variable was set to `nil` explicitly, and when it wasn's set at all:
|
445
|
+
|
446
|
+
class Foo # old behavior
|
447
|
+
extend Dry::Initializer
|
448
|
+
param :qux, optional: true
|
449
|
+
end
|
450
|
+
|
451
|
+
class Bar # new behavior
|
452
|
+
extend Dry::Initializer[undefined: false]
|
453
|
+
param :qux, optional: true
|
454
|
+
end
|
455
|
+
|
456
|
+
Foo.new.instance_variable_get(:@qux) # => Dry::Initializer::UNDEFINED
|
457
|
+
Bar.new.instance_variable_get(:@qux) # => nil
|
458
|
+
|
459
|
+
### Changed
|
460
|
+
- Fixed method definitions for performance at the load time (nepalez, flash-gordon)
|
461
|
+
|
462
|
+
## [1.2.0] [2017-03-05]
|
463
|
+
|
464
|
+
### Fixed
|
465
|
+
- The `@__options__` variable collects renamed options after default values and coercions were applied (nepalez)
|
466
|
+
|
467
|
+
## [1.1.3] [2017-03-01]
|
468
|
+
|
469
|
+
### Added
|
470
|
+
- Support for lambdas as default values (nepalez, gzigzigzeo)
|
471
|
+
|
472
|
+
## [1.1.2] [2017-02-06]
|
473
|
+
|
474
|
+
### Changed
|
475
|
+
- Remove previously defined methods before redefining them (flash-gordon)
|
476
|
+
|
477
|
+
## [1.1.1] [2017-02-04]
|
478
|
+
|
479
|
+
### Fixed
|
480
|
+
- `@__options__` collects defined options only (nepalez)
|
481
|
+
|
482
|
+
## [1.1.0] [2017-01-28]
|
483
|
+
|
484
|
+
### Added
|
485
|
+
- enhancement via `Dry::Initializer::Attribute.dispatchers` registry (nepalez)
|
486
|
+
|
487
|
+
```ruby
|
488
|
+
# Register dispatcher for `:string` option
|
489
|
+
Dry::Initializer::Attribute.dispatchers << ->(string: nil, **op) do
|
490
|
+
string ? op.merge(type: proc(&:to_s)) : op
|
491
|
+
end
|
492
|
+
|
493
|
+
# Now you can use the `:string` key for `param` and `option`
|
494
|
+
class User
|
495
|
+
extend Dry::Initializer
|
496
|
+
param :name, string: true
|
497
|
+
end
|
498
|
+
|
499
|
+
User.new(:Andy).name # => "Andy"
|
500
|
+
```
|
501
|
+
|
502
|
+
### Changed
|
503
|
+
- optimize assignments for performance (nepalez)
|
504
|
+
|
505
|
+
## [1.0.0] [2017-01-22]
|
506
|
+
|
507
|
+
In this version the code has been rewritten for simplicity
|
508
|
+
|
509
|
+
### Changed
|
510
|
+
- [BREAKING] when `param` or `option` was not defined, the corresponding **variable** is set to `Dry::Initializer::UNDEFINED`, but the **reader** (when defined) will return `nil` (nepalez)
|
511
|
+
|
512
|
+
- `Dry::Initializer` and `Dry::Initializer::Mixin` became aliases (nepalez)
|
513
|
+
|
514
|
+
### Added
|
515
|
+
- support for reloading `param` and `option` definitions (nepalez)
|
516
|
+
|
517
|
+
class User
|
518
|
+
extend Dry::Initializer
|
519
|
+
param :name
|
520
|
+
param :phone, optional: true
|
521
|
+
end
|
522
|
+
|
523
|
+
User.new # => Boom!
|
524
|
+
|
525
|
+
class Admin < User
|
526
|
+
param :name, default: proc { 'Merlin' }
|
527
|
+
end
|
528
|
+
|
529
|
+
# order of the param not changed
|
530
|
+
Admin.new.name # => "Merlin"
|
531
|
+
|
532
|
+
- support for assignment of attributes via several options (nepalez)
|
533
|
+
|
534
|
+
class User
|
535
|
+
extend Dry::Initializer
|
536
|
+
option :phone
|
537
|
+
option :number, as: :phone
|
538
|
+
end
|
539
|
+
|
540
|
+
# Both ways provide the same result
|
541
|
+
User.new(phone: '1234567890').phone # => '1234567890'
|
542
|
+
User.new(number: '1234567890').phone # => '1234567890'
|
543
|
+
|
544
|
+
## [0.11.0] [2017-01-02]
|
545
|
+
|
546
|
+
### Added
|
547
|
+
- Support of reloading `#initializer` with `super` (nepalez)
|
548
|
+
|
549
|
+
### Internal
|
550
|
+
- Refactor the way [#initializer] method is (re)defined (nepalez)
|
551
|
+
|
552
|
+
When you extend class with `Dry::Initializer::Mixin`, the initializer is
|
553
|
+
defined not "inside" the class per se, but inside the included module. The
|
554
|
+
reference to that module is stored as class-level `__initializer_mixin__`.
|
555
|
+
|
556
|
+
Mixin method [#initialize] calls another private method [#__initialize__].
|
557
|
+
It is this method to be reloaded every time you envoke a helper
|
558
|
+
`option` or `product`.
|
559
|
+
|
560
|
+
When new subclass is inherited, new mixin is added to chain of accessors,
|
561
|
+
but this time it does reload `__initialize__` only, not the `initialize`.
|
562
|
+
That is how you can safely reload initializer using `super`, but at the same
|
563
|
+
time use the whole power of dry-initializer DSL both in parent class and its
|
564
|
+
subclasses.
|
565
|
+
|
566
|
+
The whole stack of accessors looks like the following:
|
567
|
+
- Parent class mixin: `initialize` --> `__initialize__`
|
568
|
+
^
|
569
|
+
- Parent class: `initialize`
|
570
|
+
- Subclass mixin: ^ `__initialize__`
|
571
|
+
- Subclass: `initialize`
|
572
|
+
|
573
|
+
See specification `spec/custom_initializer_spec.rb` to see how this works.
|
574
|
+
|
575
|
+
## [0.10.2] [2016-12-31]
|
576
|
+
|
577
|
+
### Added
|
578
|
+
- Support of Ruby 2.4 (flas-gordon)
|
579
|
+
|
580
|
+
### Internal
|
581
|
+
- Code clearance for ROM integration (flash-gordon)
|
582
|
+
|
583
|
+
## [0.10.1] [2016-12-27]
|
584
|
+
|
585
|
+
### Fixed
|
586
|
+
- Wrong arity when there were no options and the last param had a default (nolith)
|
587
|
+
|
588
|
+
## [0.10.0] [2016-11-20]
|
589
|
+
|
590
|
+
### Deleted (BREAKING CHANGE!)
|
591
|
+
- Deprecated method DSL#using (nepalez)
|
592
|
+
|
593
|
+
## [0.9.3] [2016-11-20]
|
594
|
+
|
595
|
+
### Deprecated
|
596
|
+
- After discussion in [PR #17]: https://github.com/dry-rb/dry-initializer/pull/17)
|
597
|
+
(many thanks to @sahal2080 and @hrom512 for starting that issue and PR),
|
598
|
+
the method `using` is deprecated and will be removed from v0.10.0 (nepalez)
|
599
|
+
|
600
|
+
### Fixed
|
601
|
+
- Support of weird option names (nepalez)
|
602
|
+
|
603
|
+
```ruby
|
604
|
+
option :"First name", as: :first_name
|
605
|
+
```
|
606
|
+
|
607
|
+
## [0.9.2] [2016-11-10]
|
608
|
+
|
609
|
+
### Fixed
|
610
|
+
- Validation of attributes (params and options) (nepalez)
|
611
|
+
|
612
|
+
## [0.9.1] [2016-11-06]
|
613
|
+
|
614
|
+
### Added
|
615
|
+
- Support for renaming an option during initialization (nepalez)
|
616
|
+
|
617
|
+
option :name, as: :username # to take :name option and create :username attribute
|
618
|
+
|
619
|
+
## [0.9.0] [2016-11-06]
|
620
|
+
|
621
|
+
### Added
|
622
|
+
- The method `#initialize` is defined when a class extended the module (nepalez)
|
623
|
+
|
624
|
+
In previous versions the method was defined only by `param` and `option` calls.
|
625
|
+
|
626
|
+
### Breaking Changes
|
627
|
+
- The initializer accepts any option (but skips unknown) from the very beginning (nepalez)
|
628
|
+
|
629
|
+
### Deleted
|
630
|
+
- Deprecated methods `tolerant_to_unknown_options` and `intolerant_to_unknown_options` (nepalez)
|
631
|
+
|
632
|
+
### Internal
|
633
|
+
- Refactor scope (`using`) to support methods renaming and aliasing (nepalez)
|
634
|
+
|
635
|
+
## [0.8.1] [2016-11-05]
|
636
|
+
|
637
|
+
### Added
|
638
|
+
- Support for `dry-struct`ish syntax for constraints (type as a second parameter) (nepalez)
|
639
|
+
|
640
|
+
option :name, Dry::Types['strict.string']
|
641
|
+
|
642
|
+
## [0.8.0] [2016-11-05]
|
643
|
+
|
644
|
+
In this version we switched from key arguments to ** to support special keys:
|
645
|
+
|
646
|
+
option :end
|
647
|
+
option :begin
|
648
|
+
|
649
|
+
In previous versions this was translated to
|
650
|
+
|
651
|
+
def initialize(end:, begin:)
|
652
|
+
@end = end # BOOM! SyntaxError!
|
653
|
+
@begin = begin # Potential BOOM (unreached)
|
654
|
+
end
|
655
|
+
|
656
|
+
Now the assignment is imlemented like this:
|
657
|
+
|
658
|
+
def initialize(**__options__)
|
659
|
+
@end = __options__.fetch(:end)
|
660
|
+
@begin = __options__.fetch(:begin)
|
661
|
+
end
|
662
|
+
|
663
|
+
As a side effect of the change the initializer becomes tolerant
|
664
|
+
to any unknown option if, and only if some `option` was set explicitly.
|
665
|
+
|
666
|
+
Methods `tolerant_to_unknown_options` and `intolerant_to_unknown_options`
|
667
|
+
are deprecated and will be removed in the next version of the gem.
|
668
|
+
|
669
|
+
### Added
|
670
|
+
- support for special options like `option :end`, `option :begin` etc. (nepalez)
|
671
|
+
|
672
|
+
### Changed
|
673
|
+
- switched from key arguments to serialized hash argument in the initializer (nepalez)
|
674
|
+
|
675
|
+
### Breaking Changes
|
676
|
+
- the initializer becomes tolerant to unknown options when any `option` was set,
|
677
|
+
ignoring `intolerant_to_unknown_options` helper.
|
678
|
+
|
679
|
+
- the initializer becomes intolerant to options when no `option` was set,
|
680
|
+
ignoring `tolerant_to_unknown_options` helper.
|
681
|
+
|
682
|
+
### Deprecated
|
683
|
+
- `tolerant_to_unknown_options`
|
684
|
+
- `intolerant_to_unknown_options`
|
685
|
+
|
686
|
+
## [0.7.0] [2016-10-11]
|
687
|
+
|
688
|
+
### Added
|
689
|
+
- Shared settings with `#using` method (nepalez)
|
690
|
+
|
691
|
+
## [0.6.0] [2016-10-09]
|
692
|
+
|
693
|
+
### Added
|
694
|
+
- Support for private and protected readers in the `reader:` option (jmgarnier)
|
695
|
+
|
696
|
+
## [0.5.0] [2016-08-21]
|
697
|
+
|
698
|
+
### Added
|
699
|
+
- Allow `optional` attribute to be left undefined (nepalez)
|
700
|
+
|
701
|
+
## [0.4.0] [2016-05-28]
|
702
|
+
|
703
|
+
### Deleted (backward-incompatible changes)
|
704
|
+
- Support of modules and case equality as type constraints (nepalez)
|
705
|
+
|
706
|
+
## [0.3.3] [2016-05-28]
|
707
|
+
|
708
|
+
- Add deprecation warnings about modules and case equality as type constraints (nepalez)
|
709
|
+
|
710
|
+
## [0.3.2] [2016-05-25]
|
711
|
+
|
712
|
+
### Fixed
|
713
|
+
- Add explicit requirement for ruby 'set' (rickenharp)
|
714
|
+
|
715
|
+
## [0.3.1] [2016-05-22]
|
716
|
+
|
717
|
+
### Added
|
718
|
+
- Support for tolerance to unknown options (nepalez)
|
719
|
+
|
720
|
+
## [0.3.0] [2016-05-19]
|
721
|
+
|
722
|
+
Breaks interface for adding new plugins. Register new plugin via:
|
723
|
+
|
724
|
+
```
|
725
|
+
def self.extended(klass)
|
726
|
+
klass.register_initializer_plugin NewPlugin
|
727
|
+
end
|
728
|
+
```
|
729
|
+
|
730
|
+
instead of:
|
731
|
+
|
732
|
+
```
|
733
|
+
def self.extended(klass)
|
734
|
+
klass.initializer_builder.register NewPlugin
|
735
|
+
end
|
736
|
+
```
|
737
|
+
|
738
|
+
While the private method ##initializer_builder is still accessible
|
739
|
+
its method #register doesn't mutate the builder instance.
|
740
|
+
|
741
|
+
### Changed (backward-incompatible changes)
|
742
|
+
- Made Mixin##initializer_builder method private (nepalez)
|
743
|
+
- Add Mixin#register_initializer_plugin(plugin) method (nepalez)
|
744
|
+
|
745
|
+
### Fixed
|
746
|
+
- Prevent plugin's registry from polluting superclass (nepalez)
|
747
|
+
|
748
|
+
### Changed
|
749
|
+
- Make all instances (Builder and Signature) immutable (nepalez)
|
750
|
+
- Decouple mixin from a builder to prevent pollution (nepalez)
|
751
|
+
- Ensure default value block can use private variables (jeremyf)
|
752
|
+
|
753
|
+
## [0.2.1] [2016-05-19]
|
754
|
+
|
755
|
+
### Fixed
|
756
|
+
- Fix polluting superclass with declarations from subclass (nepalez)
|
757
|
+
|
758
|
+
### Changed
|
759
|
+
- Make all instances (Builder and Signature) immutable (nepalez)
|
760
|
+
- Decouple mixin from a builder to prevent pollution (nepalez)
|
761
|
+
- Ensure default value block can use private variables (jeremyf)
|
762
|
+
|
763
|
+
## [0.2.0] [2016-05-16]
|
764
|
+
|
765
|
+
The gem internals has been rewritten heavily to make the gem pluggable and fix
|
766
|
+
bugs in "container style". Type constraints were extracted to a plugin
|
767
|
+
that should be added explicitly.
|
768
|
+
|
769
|
+
Small extensions were added to type constraints to support constraint by any
|
770
|
+
object, and apply value coercion via `dry-types`.
|
771
|
+
|
772
|
+
Default assignments became slower (while plain type constraint are not)!
|
773
|
+
|
774
|
+
### Changed (backward-incompatible changes)
|
775
|
+
- Make dry-types constraint to coerce variables (nepalez)
|
776
|
+
|
777
|
+
```ruby
|
778
|
+
# This will coerce `name: :foo` to `"foo"`
|
779
|
+
option :name, type: Dry::Types::Coercible::String
|
780
|
+
```
|
781
|
+
|
782
|
+
- Stop supporing proc type constraint (nepalez)
|
783
|
+
|
784
|
+
```ruby
|
785
|
+
option :name, type: ->(v) { String === v } # this does NOT work any more
|
786
|
+
```
|
787
|
+
|
788
|
+
later it will be implemented via coercion plugin (not added by default):
|
789
|
+
|
790
|
+
```ruby
|
791
|
+
require 'dry/initializer/coercion'
|
792
|
+
|
793
|
+
class MyClass
|
794
|
+
extend Dry::Initializer::Mixin
|
795
|
+
extend Dry::Initializer::Coercion
|
796
|
+
|
797
|
+
option :name, coercer: ->(v) { (String === v) ? v.to_sym : fail }
|
798
|
+
end
|
799
|
+
```
|
800
|
+
|
801
|
+
### Added
|
802
|
+
- Support type constraint via every object's case equality (nepalez)
|
803
|
+
|
804
|
+
```ruby
|
805
|
+
option :name, type: /foo/
|
806
|
+
option :name, type: (1...14)
|
807
|
+
```
|
808
|
+
|
809
|
+
- Support defaults and type constraints for the "container" syntax (nepalez)
|
810
|
+
- Support adding extensions via plugin system (nepalez)
|
811
|
+
|
812
|
+
### Internal
|
813
|
+
- Private method `##__after_initialize__` is added by the `Mixin` along with `#initialize` (nepalez)
|
814
|
+
|
815
|
+
The previous implementation required defaults and types to be stored in the class method `.initializer_builder`.
|
816
|
+
That made "container" syntax to support neither defaults nor types.
|
817
|
+
|
818
|
+
Now the `#initializer` is still defined via `instance_eval(code)` for efficiency. Some operations
|
819
|
+
(like default assignments, coercions, dry-type constraints etc.) cannot be implemented in this way.
|
820
|
+
They are made inside `##__after_initialize__` callback, that is biult via `default_method(&block)`
|
821
|
+
using instance evals.
|
822
|
+
|
823
|
+
## [0.1.1] [2016-04-28]
|
824
|
+
|
825
|
+
### Added
|
826
|
+
- `include Dry::Initializer.define -> do ... end` syntax (flash-gordon)
|
827
|
+
|
828
|
+
## [0.1.0] [2016-04-26]
|
829
|
+
|
830
|
+
Class DSL splitted to mixin and container versions (thanks to @AMHOL for the idea).
|
831
|
+
Backward compatibility is broken.
|
832
|
+
|
833
|
+
### Changed (backward-incompatible changes)
|
834
|
+
- Use `extend Dry::Initializer::Mixin` instead of `extend Dry::Initializer` (nepalez)
|
835
|
+
|
836
|
+
### Added
|
837
|
+
- Use `include Dry::Initializer.define(&block)` as an alternative to extending the class (nepalez)
|
838
|
+
|
839
|
+
## [0.0.1] [2016-04-09]
|
840
|
+
|
841
|
+
First public release
|
842
|
+
|
843
|
+
[0.1.0]: https://github.com/dry-rb/dry-initializer/compare/v0.0.1...v0.1.0
|
844
|
+
[0.1.1]: https://github.com/dry-rb/dry-initializer/compare/v0.1.0...v0.1.1
|
845
|
+
[0.2.0]: https://github.com/dry-rb/dry-initializer/compare/v0.1.1...v0.2.0
|
846
|
+
[0.2.1]: https://github.com/dry-rb/dry-initializer/compare/v0.2.0...v0.2.1
|
847
|
+
[0.2.1]: https://github.com/dry-rb/dry-initializer/compare/v0.2.0...v0.2.1
|
848
|
+
[0.3.0]: https://github.com/dry-rb/dry-initializer/compare/v0.2.1...v0.3.0
|
849
|
+
[0.3.1]: https://github.com/dry-rb/dry-initializer/compare/v0.3.0...v0.3.1
|
850
|
+
[0.3.2]: https://github.com/dry-rb/dry-initializer/compare/v0.3.1...v0.3.2
|
851
|
+
[0.3.3]: https://github.com/dry-rb/dry-initializer/compare/v0.3.2...v0.3.3
|
852
|
+
[0.4.0]: https://github.com/dry-rb/dry-initializer/compare/v0.3.3...v0.4.0
|
853
|
+
[0.5.0]: https://github.com/dry-rb/dry-initializer/compare/v0.4.0...v0.5.0
|
854
|
+
[0.6.0]: https://github.com/dry-rb/dry-initializer/compare/v0.5.0...v0.6.0
|
855
|
+
[0.7.0]: https://github.com/dry-rb/dry-initializer/compare/v0.6.0...v0.7.0
|
856
|
+
[0.8.0]: https://github.com/dry-rb/dry-initializer/compare/v0.7.0...v0.8.0
|
857
|
+
[0.8.1]: https://github.com/dry-rb/dry-initializer/compare/v0.8.0...v0.8.1
|
858
|
+
[0.9.0]: https://github.com/dry-rb/dry-initializer/compare/v0.8.1...v0.9.0
|
859
|
+
[0.9.1]: https://github.com/dry-rb/dry-initializer/compare/v0.9.0...v0.9.1
|
860
|
+
[0.9.2]: https://github.com/dry-rb/dry-initializer/compare/v0.9.1...v0.9.2
|
861
|
+
[0.9.3]: https://github.com/dry-rb/dry-initializer/compare/v0.9.2...v0.9.3
|
862
|
+
[0.10.0]: https://github.com/dry-rb/dry-initializer/compare/v0.9.3...v0.10.0
|
863
|
+
[0.10.1]: https://github.com/dry-rb/dry-initializer/compare/v0.10.0...v0.10.1
|
864
|
+
[0.10.2]: https://github.com/dry-rb/dry-initializer/compare/v0.10.1...v0.10.2
|
865
|
+
[0.11.0]: https://github.com/dry-rb/dry-initializer/compare/v0.10.2...v0.11.0
|
866
|
+
[1.0.0]: https://github.com/dry-rb/dry-initializer/compare/v0.11.0...v1.0.0
|
867
|
+
[1.1.0]: https://github.com/dry-rb/dry-initializer/compare/v1.0.0...v1.1.0
|
868
|
+
[1.1.1]: https://github.com/dry-rb/dry-initializer/compare/v1.1.0...v1.1.1
|
869
|
+
[1.1.2]: https://github.com/dry-rb/dry-initializer/compare/v1.1.1...v1.1.2
|
870
|
+
[1.1.3]: https://github.com/dry-rb/dry-initializer/compare/v1.1.2...v1.1.3
|
871
|
+
[1.2.0]: https://github.com/dry-rb/dry-initializer/compare/v1.1.3...v1.2.0
|
872
|
+
[1.3.0]: https://github.com/dry-rb/dry-initializer/compare/v1.2.0...v1.3.0
|
873
|
+
[1.4.0]: https://github.com/dry-rb/dry-initializer/compare/v1.3.0...v1.4.0
|
874
|
+
[1.4.1]: https://github.com/dry-rb/dry-initializer/compare/v1.4.0...v1.4.1
|
875
|
+
[2.0.0]: https://github.com/dry-rb/dry-initializer/compare/v1.4.1...v2.0.0
|
876
|
+
[2.1.0]: https://github.com/dry-rb/dry-initializer/compare/v2.0.0...v2.1.0
|
877
|
+
[2.2.0]: https://github.com/dry-rb/dry-initializer/compare/v2.1.0...v2.2.0
|
878
|
+
[2.3.0]: https://github.com/dry-rb/dry-initializer/compare/v2.2.0...v2.3.0
|
879
|
+
[2.4.0]: https://github.com/dry-rb/dry-initializer/compare/v2.3.0...v2.4.0
|
880
|
+
[2.6.0]: https://github.com/dry-rb/dry-initializer/compare/v2.4.0...v2.5.0
|
881
|
+
[2.6.0]: https://github.com/dry-rb/dry-initializer/compare/v2.5.0...v2.6.0
|
882
|
+
[3.0.0]: https://github.com/dry-rb/dry-initializer/compare/v2.5.0...v3.0.0
|
883
|
+
[3.0.1]: https://github.com/dry-rb/dry-initializer/compare/v3.0.0...v3.0.1
|