dry-initializer 3.0.2 → 3.0.3
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/.github/ISSUE_TEMPLATE/---bug-report.md +1 -5
- data/.github/workflows/custom_ci.yml +31 -47
- data/.github/workflows/sync_configs.yml +29 -7
- data/.rspec +1 -1
- data/.rubocop.yml +19 -6
- data/CHANGELOG.md +6 -0
- data/Gemfile +27 -29
- data/Gemfile.devtools +16 -0
- data/Guardfile +3 -3
- data/LICENSE +1 -1
- data/README.md +17 -77
- data/Rakefile +4 -4
- data/benchmarks/compare_several_defaults.rb +27 -27
- data/benchmarks/plain_options.rb +14 -14
- data/benchmarks/plain_params.rb +22 -22
- data/benchmarks/with_coercion.rb +14 -14
- data/benchmarks/with_defaults.rb +17 -17
- data/benchmarks/with_defaults_and_coercion.rb +14 -14
- data/bin/.gitkeep +0 -0
- data/dry-initializer.gemspec +13 -13
- data/lib/dry-initializer.rb +1 -1
- data/lib/dry/initializer.rb +9 -9
- data/lib/dry/initializer/builders.rb +2 -2
- data/lib/dry/initializer/builders/attribute.rb +12 -7
- data/lib/dry/initializer/builders/initializer.rb +9 -13
- data/lib/dry/initializer/builders/reader.rb +3 -1
- data/lib/dry/initializer/builders/signature.rb +3 -3
- data/lib/dry/initializer/config.rb +6 -4
- data/lib/dry/initializer/definition.rb +9 -9
- data/lib/dry/initializer/dispatchers.rb +10 -10
- data/lib/dry/initializer/dispatchers/prepare_default.rb +2 -2
- data/lib/dry/initializer/dispatchers/prepare_ivar.rb +1 -1
- data/lib/dry/initializer/dispatchers/prepare_reader.rb +3 -3
- data/lib/dry/initializer/dispatchers/wrap_type.rb +1 -0
- data/lib/dry/initializer/mixin.rb +4 -4
- data/lib/dry/initializer/version.rb +5 -0
- data/lib/tasks/benchmark.rake +13 -13
- data/lib/tasks/profile.rake +16 -16
- data/project.yml +2 -0
- data/spec/attributes_spec.rb +7 -7
- data/spec/coercion_of_nil_spec.rb +3 -3
- data/spec/custom_dispatchers_spec.rb +6 -6
- data/spec/custom_initializer_spec.rb +2 -2
- data/spec/default_values_spec.rb +9 -9
- data/spec/definition_spec.rb +10 -10
- data/spec/invalid_default_spec.rb +2 -2
- data/spec/list_type_spec.rb +8 -8
- data/spec/missed_default_spec.rb +2 -2
- data/spec/nested_type_spec.rb +10 -10
- data/spec/optional_spec.rb +16 -16
- data/spec/options_tolerance_spec.rb +2 -2
- data/spec/public_attributes_utility_spec.rb +5 -5
- data/spec/reader_spec.rb +13 -13
- data/spec/repetitive_definitions_spec.rb +9 -9
- data/spec/several_assignments_spec.rb +9 -9
- data/spec/spec_helper.rb +3 -8
- data/spec/subclassing_spec.rb +5 -5
- data/spec/support/coverage.rb +7 -0
- data/spec/support/warnings.rb +7 -0
- data/spec/type_argument_spec.rb +13 -13
- data/spec/type_constraint_spec.rb +44 -26
- data/spec/value_coercion_via_dry_types_spec.rb +7 -7
- metadata +11 -31
data/bin/.gitkeep
ADDED
File without changes
|
data/dry-initializer.gemspec
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
+
require File.expand_path('lib/dry/initializer/version', __dir__)
|
2
|
+
|
1
3
|
Gem::Specification.new do |gem|
|
2
|
-
gem.name =
|
3
|
-
gem.version =
|
4
|
-
gem.author = [
|
5
|
-
gem.email =
|
6
|
-
gem.homepage =
|
7
|
-
gem.summary =
|
8
|
-
gem.license =
|
4
|
+
gem.name = 'dry-initializer'
|
5
|
+
gem.version = Dry::Initializer::VERSION
|
6
|
+
gem.author = ['Vladimir Kochnev (marshall-lee)', 'Andrew Kozin (nepalez)']
|
7
|
+
gem.email = 'andrew.kozin@gmail.com'
|
8
|
+
gem.homepage = 'https://github.com/dry-rb/dry-initializer'
|
9
|
+
gem.summary = 'DSL for declaring params and options of the initializer'
|
10
|
+
gem.license = 'MIT'
|
9
11
|
|
10
12
|
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
11
13
|
gem.test_files = gem.files.grep(/^spec/)
|
12
|
-
gem.extra_rdoc_files = Dir[
|
14
|
+
gem.extra_rdoc_files = Dir['README.md', 'LICENSE', 'CHANGELOG.md']
|
13
15
|
|
14
|
-
gem.required_ruby_version =
|
16
|
+
gem.required_ruby_version = '>= 2.3'
|
15
17
|
|
16
|
-
gem.add_development_dependency
|
17
|
-
gem.add_development_dependency
|
18
|
-
gem.add_development_dependency "dry-types", "> 0.5.1"
|
19
|
-
gem.add_development_dependency "rubocop", "~> 0.49.0"
|
18
|
+
gem.add_development_dependency 'rspec', '~> 3.0'
|
19
|
+
gem.add_development_dependency 'rake', '> 10'
|
20
20
|
end
|
data/lib/dry-initializer.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require_relative
|
1
|
+
require_relative 'dry/initializer'
|
data/lib/dry/initializer.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'set'
|
2
2
|
|
3
3
|
# Namespace for gems in a dry-rb community
|
4
4
|
module Dry
|
@@ -6,13 +6,13 @@ module Dry
|
|
6
6
|
# DSL for declaring params and options of class initializers
|
7
7
|
#
|
8
8
|
module Initializer
|
9
|
-
require_relative
|
10
|
-
require_relative
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
14
|
-
require_relative
|
15
|
-
require_relative
|
9
|
+
require_relative 'initializer/undefined'
|
10
|
+
require_relative 'initializer/dsl'
|
11
|
+
require_relative 'initializer/definition'
|
12
|
+
require_relative 'initializer/builders'
|
13
|
+
require_relative 'initializer/config'
|
14
|
+
require_relative 'initializer/mixin'
|
15
|
+
require_relative 'initializer/dispatchers'
|
16
16
|
|
17
17
|
# Adds methods [.[]] and [.define]
|
18
18
|
extend DSL
|
@@ -56,6 +56,6 @@ module Dry
|
|
56
56
|
dry_initializer.children << config
|
57
57
|
end
|
58
58
|
|
59
|
-
require_relative
|
59
|
+
require_relative 'initializer/struct'
|
60
60
|
end
|
61
61
|
end
|
@@ -20,17 +20,17 @@ module Dry::Initializer::Builders
|
|
20
20
|
@default = definition.default
|
21
21
|
@source = definition.source
|
22
22
|
@ivar = definition.ivar
|
23
|
-
@null = definition.null ?
|
24
|
-
@opts =
|
25
|
-
@congif =
|
26
|
-
@item =
|
27
|
-
@val = @option ?
|
23
|
+
@null = definition.null ? 'Dry::Initializer::UNDEFINED' : 'nil'
|
24
|
+
@opts = '__dry_initializer_options__'
|
25
|
+
@congif = '__dry_initializer_config__'
|
26
|
+
@item = '__dry_initializer_definition__'
|
27
|
+
@val = @option ? '__dry_initializer_value__' : @source
|
28
28
|
end
|
29
29
|
# rubocop: enable Metrics/MethodLength
|
30
30
|
|
31
31
|
def lines
|
32
32
|
[
|
33
|
-
|
33
|
+
'',
|
34
34
|
definition_line,
|
35
35
|
reader_line,
|
36
36
|
default_line,
|
@@ -41,6 +41,7 @@ module Dry::Initializer::Builders
|
|
41
41
|
|
42
42
|
def reader_line
|
43
43
|
return unless @option
|
44
|
+
|
44
45
|
@optional ? optional_reader : required_reader
|
45
46
|
end
|
46
47
|
|
@@ -55,18 +56,22 @@ module Dry::Initializer::Builders
|
|
55
56
|
|
56
57
|
def definition_line
|
57
58
|
return unless @type || @default
|
59
|
+
|
58
60
|
"#{@item} = __dry_initializer_config__.definitions[:'#{@source}']"
|
59
61
|
end
|
60
62
|
|
61
63
|
def default_line
|
62
64
|
return unless @default
|
65
|
+
|
63
66
|
"#{@val} = instance_exec(&#{@item}.default) if #{@null} == #{@val}"
|
64
67
|
end
|
65
68
|
|
66
69
|
def coercion_line
|
67
70
|
return unless @type
|
71
|
+
|
68
72
|
arity = @type.is_a?(Proc) ? @type.arity : @type.method(:call).arity
|
69
|
-
|
73
|
+
|
74
|
+
if arity.abs == 1 || Dry::Types::Type.equal?(@type)
|
70
75
|
"#{@val} = #{@item}.type.call(#{@val}) unless #{@null} == #{@val}"
|
71
76
|
else
|
72
77
|
"#{@val} = #{@item}.type.call(#{@val}, self) unless #{@null} == #{@val}"
|
@@ -1,8 +1,8 @@
|
|
1
1
|
module Dry::Initializer::Builders
|
2
2
|
# @private
|
3
3
|
class Initializer
|
4
|
-
require_relative
|
5
|
-
require_relative
|
4
|
+
require_relative 'signature'
|
5
|
+
require_relative 'attribute'
|
6
6
|
|
7
7
|
def self.[](config)
|
8
8
|
new(config).call
|
@@ -30,8 +30,8 @@ module Dry::Initializer::Builders
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def undef_line
|
33
|
-
|
34
|
-
|
33
|
+
'undef :__dry_initializer_initialize__' \
|
34
|
+
' if private_method_defined? :__dry_initializer_initialize__'
|
35
35
|
end
|
36
36
|
|
37
37
|
def define_line
|
@@ -40,22 +40,18 @@ module Dry::Initializer::Builders
|
|
40
40
|
|
41
41
|
def params_lines
|
42
42
|
@definitions.reject(&:option)
|
43
|
-
|
44
|
-
|
43
|
+
.flat_map { |item| Attribute[item] }
|
44
|
+
.map { |line| ' ' << line }
|
45
45
|
end
|
46
46
|
|
47
47
|
def options_lines
|
48
48
|
@definitions.select(&:option)
|
49
|
-
|
50
|
-
|
49
|
+
.flat_map { |item| Attribute[item] }
|
50
|
+
.map { |line| ' ' << line }
|
51
51
|
end
|
52
52
|
|
53
53
|
def end_line
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
def private_line
|
58
|
-
"private :__dry_initializer_initialize__"
|
54
|
+
'end'
|
59
55
|
end
|
60
56
|
end
|
61
57
|
end
|
@@ -30,16 +30,18 @@ module Dry::Initializer::Builders
|
|
30
30
|
|
31
31
|
def attribute_line
|
32
32
|
return unless @reader
|
33
|
+
|
33
34
|
"attr_reader :#{@target}" unless @null
|
34
35
|
end
|
35
36
|
|
36
37
|
def method_lines
|
37
38
|
return unless @reader
|
38
39
|
return unless @null
|
40
|
+
|
39
41
|
[
|
40
42
|
"def #{@target}",
|
41
43
|
" #{@ivar} unless Dry::Initializer::UNDEFINED == #{@ivar}",
|
42
|
-
|
44
|
+
'end'
|
43
45
|
]
|
44
46
|
end
|
45
47
|
|
@@ -6,7 +6,7 @@ module Dry::Initializer::Builders
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def call
|
9
|
-
[*required_params, *optional_params,
|
9
|
+
[*required_params, *optional_params, '*', options].compact.join(', ')
|
10
10
|
end
|
11
11
|
|
12
12
|
private
|
@@ -14,7 +14,7 @@ module Dry::Initializer::Builders
|
|
14
14
|
def initialize(config)
|
15
15
|
@config = config
|
16
16
|
@options = config.options.any?
|
17
|
-
@null = config.null ?
|
17
|
+
@null = config.null ? 'Dry::Initializer::UNDEFINED' : 'nil'
|
18
18
|
end
|
19
19
|
|
20
20
|
def required_params
|
@@ -26,7 +26,7 @@ module Dry::Initializer::Builders
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def options
|
29
|
-
|
29
|
+
'**__dry_initializer_options__' if @options
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -78,6 +78,7 @@ module Dry::Initializer
|
|
78
78
|
definitions.values.each_with_object({}) do |item, obj|
|
79
79
|
key = item.target
|
80
80
|
next unless instance.respond_to? key
|
81
|
+
|
81
82
|
val = instance.send(key)
|
82
83
|
obj[key] = val unless null == val
|
83
84
|
end
|
@@ -114,7 +115,7 @@ module Dry::Initializer
|
|
114
115
|
# @return [String]
|
115
116
|
def inch
|
116
117
|
line = Builders::Signature[self]
|
117
|
-
line = line.gsub(
|
118
|
+
line = line.gsub('__dry_initializer_options__', 'options')
|
118
119
|
lines = ["@!method initialize(#{line})"]
|
119
120
|
lines += ["Initializes an instance of #{extended_class}"]
|
120
121
|
lines += definitions.values.map(&:inch)
|
@@ -138,10 +139,10 @@ module Dry::Initializer
|
|
138
139
|
opts = {
|
139
140
|
parent: extended_class,
|
140
141
|
option: option,
|
141
|
-
null:
|
142
|
+
null: null,
|
142
143
|
source: name,
|
143
|
-
type:
|
144
|
-
block:
|
144
|
+
type: type,
|
145
|
+
block: block,
|
145
146
|
**opts
|
146
147
|
}
|
147
148
|
|
@@ -163,6 +164,7 @@ module Dry::Initializer
|
|
163
164
|
def check_type(previous, current)
|
164
165
|
return current unless previous
|
165
166
|
return current if previous.option == current.option
|
167
|
+
|
166
168
|
raise SyntaxError,
|
167
169
|
"cannot reload #{previous} of #{extended_class.superclass}" \
|
168
170
|
" by #{current} of its subclass #{extended_class}"
|
@@ -14,17 +14,17 @@ module Dry::Initializer
|
|
14
14
|
|
15
15
|
def options
|
16
16
|
{
|
17
|
-
as:
|
18
|
-
type:
|
17
|
+
as: target,
|
18
|
+
type: type,
|
19
19
|
optional: optional,
|
20
|
-
default:
|
21
|
-
reader:
|
22
|
-
desc:
|
20
|
+
default: default,
|
21
|
+
reader: reader,
|
22
|
+
desc: desc
|
23
23
|
}.reject { |_, value| value.nil? }
|
24
24
|
end
|
25
25
|
|
26
26
|
def name
|
27
|
-
@name ||= (option ?
|
27
|
+
@name ||= (option ? 'option' : 'parameter') << " '#{source}'"
|
28
28
|
end
|
29
29
|
alias to_s name
|
30
30
|
alias to_str name
|
@@ -39,10 +39,10 @@ module Dry::Initializer
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def inch
|
42
|
-
@inch ||= (option ?
|
43
|
-
text <<
|
42
|
+
@inch ||= (option ? '@option' : '@param ').tap do |text|
|
43
|
+
text << ' [Object]'
|
44
44
|
text << (option ? " :#{source}" : " #{source}")
|
45
|
-
text << (optional ?
|
45
|
+
text << (optional ? ' (optional)' : ' (required)')
|
46
46
|
text << " #{desc}" if desc
|
47
47
|
end
|
48
48
|
end
|
@@ -91,16 +91,16 @@ module Dry::Initializer::Dispatchers
|
|
91
91
|
|
92
92
|
private
|
93
93
|
|
94
|
-
require_relative
|
95
|
-
require_relative
|
96
|
-
require_relative
|
97
|
-
require_relative
|
98
|
-
require_relative
|
99
|
-
require_relative
|
100
|
-
require_relative
|
101
|
-
require_relative
|
102
|
-
require_relative
|
103
|
-
require_relative
|
94
|
+
require_relative 'dispatchers/build_nested_type'
|
95
|
+
require_relative 'dispatchers/check_type'
|
96
|
+
require_relative 'dispatchers/prepare_default'
|
97
|
+
require_relative 'dispatchers/prepare_ivar'
|
98
|
+
require_relative 'dispatchers/prepare_optional'
|
99
|
+
require_relative 'dispatchers/prepare_reader'
|
100
|
+
require_relative 'dispatchers/prepare_source'
|
101
|
+
require_relative 'dispatchers/prepare_target'
|
102
|
+
require_relative 'dispatchers/unwrap_type'
|
103
|
+
require_relative 'dispatchers/wrap_type'
|
104
104
|
|
105
105
|
def pipeline
|
106
106
|
@pipeline ||= [
|
@@ -34,7 +34,7 @@ module Dry::Initializer::Dispatchers::PrepareDefault
|
|
34
34
|
|
35
35
|
def invalid!(default)
|
36
36
|
raise TypeError, "The #{default.inspect} should be" \
|
37
|
-
|
38
|
-
|
37
|
+
' either convertable to proc with no arguments,' \
|
38
|
+
' or respond to #call without arguments.'
|
39
39
|
end
|
40
40
|
end
|
@@ -6,9 +6,9 @@ module Dry::Initializer::Dispatchers::PrepareReader
|
|
6
6
|
|
7
7
|
def call(target: nil, reader: :public, **options)
|
8
8
|
reader = case reader.to_s
|
9
|
-
when
|
10
|
-
when
|
11
|
-
when
|
9
|
+
when 'false', '' then nil
|
10
|
+
when 'true' then :public
|
11
|
+
when 'public', 'private', 'protected' then reader.to_sym
|
12
12
|
else invalid_reader!(target, reader)
|
13
13
|
end
|
14
14
|
|
@@ -4,12 +4,12 @@ module Dry::Initializer
|
|
4
4
|
extend DSL # @deprecated
|
5
5
|
include Dry::Initializer # @deprecated
|
6
6
|
def self.extended(klass) # @deprecated
|
7
|
-
warn
|
8
|
-
|
7
|
+
warn '[DEPRECATED] Use Dry::Initializer instead of its alias' \
|
8
|
+
' Dry::Initializer::Mixin. The later will be removed in v2.1.0'
|
9
9
|
super
|
10
10
|
end
|
11
11
|
|
12
|
-
require_relative
|
13
|
-
require_relative
|
12
|
+
require_relative 'mixin/root'
|
13
|
+
require_relative 'mixin/local'
|
14
14
|
end
|
15
15
|
end
|
data/lib/tasks/benchmark.rake
CHANGED
@@ -1,36 +1,36 @@
|
|
1
1
|
namespace :benchmark do
|
2
|
-
desc
|
2
|
+
desc 'Runs benchmarks for plain params'
|
3
3
|
task :plain_params do
|
4
|
-
system
|
4
|
+
system 'ruby benchmarks/plain_params.rb'
|
5
5
|
end
|
6
6
|
|
7
|
-
desc
|
7
|
+
desc 'Runs benchmarks for plain options'
|
8
8
|
task :plain_options do
|
9
|
-
system
|
9
|
+
system 'ruby benchmarks/plain_options.rb'
|
10
10
|
end
|
11
11
|
|
12
|
-
desc
|
12
|
+
desc 'Runs benchmarks for value coercion'
|
13
13
|
task :with_coercion do
|
14
|
-
system
|
14
|
+
system 'ruby benchmarks/with_coercion.rb'
|
15
15
|
end
|
16
16
|
|
17
|
-
desc
|
17
|
+
desc 'Runs benchmarks with defaults'
|
18
18
|
task :with_defaults do
|
19
|
-
system
|
19
|
+
system 'ruby benchmarks/with_defaults.rb'
|
20
20
|
end
|
21
21
|
|
22
|
-
desc
|
22
|
+
desc 'Runs benchmarks with defaults and coercion'
|
23
23
|
task :with_defaults_and_coercion do
|
24
|
-
system
|
24
|
+
system 'ruby benchmarks/with_defaults_and_coercion.rb'
|
25
25
|
end
|
26
26
|
|
27
|
-
desc
|
27
|
+
desc 'Runs benchmarks for several defaults'
|
28
28
|
task :compare_several_defaults do
|
29
|
-
system
|
29
|
+
system 'ruby benchmarks/with_several_defaults.rb'
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
desc
|
33
|
+
desc 'Runs all benchmarks'
|
34
34
|
task benchmark: %i[
|
35
35
|
benchmark:plain_params
|
36
36
|
benchmark:plain_options
|