dry-initializer 1.4.1 → 2.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/.rubocop.yml +8 -8
- data/.travis.yml +0 -3
- data/CHANGELOG.md +339 -196
- data/LICENSE.txt +1 -1
- data/README.md +3 -3
- data/Rakefile +2 -47
- data/benchmarks/{several_defaults.rb → compare_several_defaults.rb} +4 -4
- data/benchmarks/{without_options.rb → plain_options.rb} +20 -9
- data/benchmarks/{params.rb → plain_params.rb} +20 -9
- data/benchmarks/{with_types.rb → with_coercion.rb} +20 -9
- data/benchmarks/with_defaults.rb +19 -8
- data/benchmarks/{with_types_and_defaults.rb → with_defaults_and_coercion.rb} +21 -10
- data/dry-initializer.gemspec +3 -3
- data/lib/dry/initializer/builders/attribute.rb +76 -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/builders.rb +7 -0
- data/lib/dry/initializer/config.rb +161 -0
- data/lib/dry/initializer/definition.rb +93 -0
- data/lib/dry/initializer/dsl.rb +43 -0
- data/lib/dry/initializer/mixin/local.rb +19 -0
- data/lib/dry/initializer/mixin/root.rb +10 -0
- data/lib/dry/initializer/mixin.rb +15 -0
- data/lib/dry/initializer.rb +45 -41
- data/lib/tasks/benchmark.rake +41 -0
- data/lib/tasks/profile.rake +78 -0
- data/spec/{options_var_spec.rb → attributes_spec.rb} +9 -9
- data/spec/custom_initializer_spec.rb +1 -1
- data/spec/default_values_spec.rb +6 -6
- data/spec/definition_spec.rb +21 -14
- data/spec/invalid_default_spec.rb +2 -2
- data/spec/missed_default_spec.rb +2 -2
- data/spec/optional_spec.rb +2 -2
- data/spec/options_tolerance_spec.rb +1 -1
- data/spec/public_attributes_utility_spec.rb +22 -0
- data/spec/reader_spec.rb +11 -11
- data/spec/repetitive_definitions_spec.rb +5 -5
- data/spec/several_assignments_spec.rb +1 -1
- data/spec/spec_helper.rb +5 -0
- data/spec/subclassing_spec.rb +7 -3
- data/spec/type_argument_spec.rb +1 -1
- data/spec/type_constraint_spec.rb +2 -2
- data/spec/value_coercion_via_dry_types_spec.rb +1 -1
- metadata +27 -27
- data/benchmarks/options.rb +0 -54
- data/benchmarks/params_vs_options.rb +0 -35
- data/benchmarks/profiler.rb +0 -28
- data/lib/dry/initializer/attribute.rb +0 -123
- data/lib/dry/initializer/builder.rb +0 -127
- data/lib/dry/initializer/class_dsl.rb +0 -37
- data/lib/dry/initializer/exceptions/default_value_error.rb +0 -8
- data/lib/dry/initializer/exceptions/params_order_error.rb +0 -8
- data/lib/dry/initializer/exceptions/type_constraint_error.rb +0 -7
- data/lib/dry/initializer/instance_dsl.rb +0 -15
- data/lib/dry/initializer/option.rb +0 -61
- data/lib/dry/initializer/param.rb +0 -52
- data/spec/gem_enhancement_spec.rb +0 -18
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2016 Andrew Kozin (nepalez), Vladimir Kochnev (marshall-lee)
|
3
|
+
Copyright (c) 2016-2017 Andrew Kozin (nepalez), Vladimir Kochnev (marshall-lee)
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -49,10 +49,10 @@ class User
|
|
49
49
|
extend Dry::Initializer::Mixin
|
50
50
|
|
51
51
|
# Params of the initializer along with corresponding readers
|
52
|
-
param :name,
|
53
|
-
param :role, default:
|
52
|
+
param :name, proc(&:to_s)
|
53
|
+
param :role, default: -> { 'customer' }
|
54
54
|
# Options of the initializer along with corresponding readers
|
55
|
-
option :admin, default:
|
55
|
+
option :admin, default: -> { false }
|
56
56
|
option :vip, optional: true
|
57
57
|
end
|
58
58
|
|
data/Rakefile
CHANGED
@@ -4,50 +4,5 @@ Bundler::GemHelper.install_tasks
|
|
4
4
|
require "rspec/core/rake_task"
|
5
5
|
RSpec::Core::RakeTask.new :default
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
task :without_options do
|
10
|
-
system "ruby benchmarks/without_options.rb"
|
11
|
-
end
|
12
|
-
|
13
|
-
desc "Runs benchmarks for several defaults"
|
14
|
-
task :several_defaults do
|
15
|
-
system "ruby benchmarks/several_defaults.rb"
|
16
|
-
end
|
17
|
-
|
18
|
-
desc "Runs benchmarks for defaults of params vs. options"
|
19
|
-
task :params_vs_options do
|
20
|
-
system "ruby benchmarks/params_vs_options.rb"
|
21
|
-
end
|
22
|
-
|
23
|
-
desc "Runs benchmarks with types"
|
24
|
-
task :with_types do
|
25
|
-
system "ruby benchmarks/with_types.rb"
|
26
|
-
end
|
27
|
-
|
28
|
-
desc "Runs benchmarks with defaults"
|
29
|
-
task :with_defaults do
|
30
|
-
system "ruby benchmarks/with_defaults.rb"
|
31
|
-
end
|
32
|
-
|
33
|
-
desc "Runs benchmarks with types and defaults"
|
34
|
-
task :with_types_and_defaults do
|
35
|
-
system "ruby benchmarks/with_types_and_defaults.rb"
|
36
|
-
end
|
37
|
-
|
38
|
-
desc "Runs benchmarks for plain params"
|
39
|
-
task :params do
|
40
|
-
system "ruby benchmarks/params.rb"
|
41
|
-
end
|
42
|
-
|
43
|
-
desc "Runs benchmarks various opts"
|
44
|
-
task :options do
|
45
|
-
system "ruby benchmarks/options.rb"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
desc "Runs profiler"
|
50
|
-
task :profile do
|
51
|
-
system "ruby benchmarks/profiler.rb && " \
|
52
|
-
"dot -Tpng ./tmp/profile.dot > ./tmp/profile.png"
|
53
|
-
end
|
7
|
+
load "lib/tasks/benchmark.rake"
|
8
|
+
load "lib/tasks/profile.rake"
|
@@ -2,7 +2,7 @@ Bundler.require(:benchmarks)
|
|
2
2
|
|
3
3
|
require "dry-initializer"
|
4
4
|
class WithoutDefaults
|
5
|
-
extend Dry::Initializer
|
5
|
+
extend Dry::Initializer
|
6
6
|
|
7
7
|
param :foo
|
8
8
|
param :bar
|
@@ -10,7 +10,7 @@ class WithoutDefaults
|
|
10
10
|
end
|
11
11
|
|
12
12
|
class WithOneDefault
|
13
|
-
extend Dry::Initializer
|
13
|
+
extend Dry::Initializer
|
14
14
|
|
15
15
|
param :foo
|
16
16
|
param :bar
|
@@ -18,7 +18,7 @@ class WithOneDefault
|
|
18
18
|
end
|
19
19
|
|
20
20
|
class WithTwoDefaults
|
21
|
-
extend Dry::Initializer
|
21
|
+
extend Dry::Initializer
|
22
22
|
|
23
23
|
param :foo
|
24
24
|
param :bar, default: proc { "BAR" }
|
@@ -26,7 +26,7 @@ class WithTwoDefaults
|
|
26
26
|
end
|
27
27
|
|
28
28
|
class WithThreeDefaults
|
29
|
-
extend Dry::Initializer
|
29
|
+
extend Dry::Initializer
|
30
30
|
|
31
31
|
param :foo, default: proc { "FOO" }
|
32
32
|
param :bar, default: proc { "BAR" }
|
@@ -1,5 +1,20 @@
|
|
1
1
|
Bundler.require(:benchmarks)
|
2
2
|
|
3
|
+
require "dry-initializer"
|
4
|
+
class DryTest
|
5
|
+
extend Dry::Initializer[undefined: false]
|
6
|
+
|
7
|
+
option :foo
|
8
|
+
option :bar
|
9
|
+
end
|
10
|
+
|
11
|
+
class DryTestUndefined
|
12
|
+
extend Dry::Initializer
|
13
|
+
|
14
|
+
option :foo
|
15
|
+
option :bar
|
16
|
+
end
|
17
|
+
|
3
18
|
class PlainRubyTest
|
4
19
|
attr_reader :foo, :bar
|
5
20
|
|
@@ -9,14 +24,6 @@ class PlainRubyTest
|
|
9
24
|
end
|
10
25
|
end
|
11
26
|
|
12
|
-
require "dry-initializer"
|
13
|
-
class DryTest
|
14
|
-
extend Dry::Initializer::Mixin
|
15
|
-
|
16
|
-
option :foo
|
17
|
-
option :bar
|
18
|
-
end
|
19
|
-
|
20
27
|
require "anima"
|
21
28
|
class AnimaTest
|
22
29
|
include Anima.new(:foo, :bar)
|
@@ -27,7 +34,7 @@ class KwattrTest
|
|
27
34
|
kwattr :foo, :bar
|
28
35
|
end
|
29
36
|
|
30
|
-
puts "Benchmark for instantiation
|
37
|
+
puts "Benchmark for instantiation with plain options"
|
31
38
|
|
32
39
|
Benchmark.ips do |x|
|
33
40
|
x.config time: 15, warmup: 10
|
@@ -40,6 +47,10 @@ Benchmark.ips do |x|
|
|
40
47
|
DryTest.new foo: "FOO", bar: "BAR"
|
41
48
|
end
|
42
49
|
|
50
|
+
x.report("dry-initializer (with UNDEFINED)") do
|
51
|
+
DryTestUndefined.new foo: "FOO", bar: "BAR"
|
52
|
+
end
|
53
|
+
|
43
54
|
x.report("anima") do
|
44
55
|
AnimaTest.new foo: "FOO", bar: "BAR"
|
45
56
|
end
|
@@ -1,5 +1,20 @@
|
|
1
1
|
Bundler.require(:benchmarks)
|
2
2
|
|
3
|
+
require "dry-initializer"
|
4
|
+
class DryTest
|
5
|
+
extend Dry::Initializer[undefined: false]
|
6
|
+
|
7
|
+
param :foo
|
8
|
+
param :bar
|
9
|
+
end
|
10
|
+
|
11
|
+
class DryTestUndefined
|
12
|
+
extend Dry::Initializer
|
13
|
+
|
14
|
+
param :foo
|
15
|
+
param :bar
|
16
|
+
end
|
17
|
+
|
3
18
|
class PlainRubyTest
|
4
19
|
attr_reader :foo, :bar
|
5
20
|
|
@@ -11,14 +26,6 @@ end
|
|
11
26
|
|
12
27
|
StructTest = Struct.new(:foo, :bar)
|
13
28
|
|
14
|
-
require "dry-initializer"
|
15
|
-
class DryTest
|
16
|
-
extend Dry::Initializer
|
17
|
-
|
18
|
-
param :foo
|
19
|
-
param :bar
|
20
|
-
end
|
21
|
-
|
22
29
|
require "concord"
|
23
30
|
class ConcordTest
|
24
31
|
include Concord.new(:foo, :bar)
|
@@ -36,7 +43,7 @@ class AttrExtrasText
|
|
36
43
|
attr_reader :foo, :bar
|
37
44
|
end
|
38
45
|
|
39
|
-
puts "Benchmark for instantiation
|
46
|
+
puts "Benchmark for instantiation with plain params"
|
40
47
|
|
41
48
|
Benchmark.ips do |x|
|
42
49
|
x.config time: 15, warmup: 10
|
@@ -61,6 +68,10 @@ Benchmark.ips do |x|
|
|
61
68
|
DryTest.new "FOO", "BAR"
|
62
69
|
end
|
63
70
|
|
71
|
+
x.report("dry-initializer (with UNDEFINED)") do
|
72
|
+
DryTestUndefined.new "FOO", "BAR"
|
73
|
+
end
|
74
|
+
|
64
75
|
x.report("concord") do
|
65
76
|
ConcordTest.new "FOO", "BAR"
|
66
77
|
end
|
@@ -1,5 +1,20 @@
|
|
1
1
|
Bundler.require(:benchmarks)
|
2
2
|
|
3
|
+
require "dry-initializer"
|
4
|
+
class DryTest
|
5
|
+
extend Dry::Initializer[undefined: false]
|
6
|
+
|
7
|
+
option :foo, proc(&:to_s)
|
8
|
+
option :bar, proc(&:to_s)
|
9
|
+
end
|
10
|
+
|
11
|
+
class DryTestUndefined
|
12
|
+
extend Dry::Initializer
|
13
|
+
|
14
|
+
option :foo, proc(&:to_s)
|
15
|
+
option :bar, proc(&:to_s)
|
16
|
+
end
|
17
|
+
|
3
18
|
class PlainRubyTest
|
4
19
|
attr_reader :foo, :bar
|
5
20
|
|
@@ -9,14 +24,6 @@ class PlainRubyTest
|
|
9
24
|
end
|
10
25
|
end
|
11
26
|
|
12
|
-
require "dry-initializer"
|
13
|
-
class DryTest
|
14
|
-
extend Dry::Initializer::Mixin
|
15
|
-
|
16
|
-
option :foo, &(:to_s)
|
17
|
-
option :bar, &(:to_s)
|
18
|
-
end
|
19
|
-
|
20
27
|
require "virtus"
|
21
28
|
class VirtusTest
|
22
29
|
include Virtus.model
|
@@ -35,7 +42,7 @@ class FastAttributesTest
|
|
35
42
|
end
|
36
43
|
end
|
37
44
|
|
38
|
-
puts "Benchmark for instantiation with
|
45
|
+
puts "Benchmark for instantiation with coercion"
|
39
46
|
|
40
47
|
Benchmark.ips do |x|
|
41
48
|
x.config time: 15, warmup: 10
|
@@ -48,6 +55,10 @@ Benchmark.ips do |x|
|
|
48
55
|
DryTest.new foo: "FOO", bar: "BAR"
|
49
56
|
end
|
50
57
|
|
58
|
+
x.report("dry-initializer (with UNDEFINED)") do
|
59
|
+
DryTestUndefined.new foo: "FOO", bar: "BAR"
|
60
|
+
end
|
61
|
+
|
51
62
|
x.report("virtus") do
|
52
63
|
VirtusTest.new foo: "FOO", bar: "BAR"
|
53
64
|
end
|
data/benchmarks/with_defaults.rb
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
Bundler.require(:benchmarks)
|
2
2
|
|
3
|
+
require "dry-initializer"
|
4
|
+
class DryTest
|
5
|
+
extend Dry::Initializer[undefined: false]
|
6
|
+
|
7
|
+
option :foo, default: -> { "FOO" }
|
8
|
+
option :bar, default: -> { "BAR" }
|
9
|
+
end
|
10
|
+
|
11
|
+
class DryTestUndefined
|
12
|
+
extend Dry::Initializer
|
13
|
+
|
14
|
+
option :foo, default: -> { "FOO" }
|
15
|
+
option :bar, default: -> { "BAR" }
|
16
|
+
end
|
17
|
+
|
3
18
|
class PlainRubyTest
|
4
19
|
attr_reader :foo, :bar
|
5
20
|
|
@@ -9,14 +24,6 @@ class PlainRubyTest
|
|
9
24
|
end
|
10
25
|
end
|
11
26
|
|
12
|
-
require "dry-initializer"
|
13
|
-
class DryTest
|
14
|
-
extend Dry::Initializer::Mixin
|
15
|
-
|
16
|
-
option :foo, default: proc { "FOO" }
|
17
|
-
option :bar, default: proc { "BAR" }
|
18
|
-
end
|
19
|
-
|
20
27
|
require "kwattr"
|
21
28
|
class KwattrTest
|
22
29
|
kwattr foo: "FOO", bar: "BAR"
|
@@ -43,6 +50,10 @@ Benchmark.ips do |x|
|
|
43
50
|
DryTest.new
|
44
51
|
end
|
45
52
|
|
53
|
+
x.report("dry-initializer (with UNDEFINED)") do
|
54
|
+
DryTestUndefined.new
|
55
|
+
end
|
56
|
+
|
46
57
|
x.report("kwattr") do
|
47
58
|
KwattrTest.new
|
48
59
|
end
|
@@ -1,24 +1,31 @@
|
|
1
1
|
Bundler.require(:benchmarks)
|
2
2
|
|
3
|
+
require "dry-initializer"
|
4
|
+
class DryTest
|
5
|
+
extend Dry::Initializer[undefined: false]
|
6
|
+
|
7
|
+
option :foo, proc(&:to_s), default: -> { "FOO" }
|
8
|
+
option :bar, proc(&:to_s), default: -> { "BAR" }
|
9
|
+
end
|
10
|
+
|
11
|
+
class DryTestUndefined
|
12
|
+
extend Dry::Initializer
|
13
|
+
|
14
|
+
option :foo, proc(&:to_s), default: -> { "FOO" }
|
15
|
+
option :bar, proc(&:to_s), default: -> { "BAR" }
|
16
|
+
end
|
17
|
+
|
3
18
|
class PlainRubyTest
|
4
19
|
attr_reader :foo, :bar
|
5
20
|
|
6
21
|
def initialize(foo: "FOO", bar: "BAR")
|
7
22
|
@foo = foo
|
8
23
|
@bar = bar
|
9
|
-
|
10
|
-
|
24
|
+
raise TypeError unless String === @foo
|
25
|
+
raise TypeError unless String === @bar
|
11
26
|
end
|
12
27
|
end
|
13
28
|
|
14
|
-
require "dry-initializer"
|
15
|
-
class DryTest
|
16
|
-
extend Dry::Initializer::Mixin
|
17
|
-
|
18
|
-
option :foo, proc(&:to_s), default: proc { "FOO" }
|
19
|
-
option :bar, proc(&:to_s), default: proc { "BAR" }
|
20
|
-
end
|
21
|
-
|
22
29
|
require "virtus"
|
23
30
|
class VirtusTest
|
24
31
|
include Virtus.model
|
@@ -40,6 +47,10 @@ Benchmark.ips do |x|
|
|
40
47
|
DryTest.new
|
41
48
|
end
|
42
49
|
|
50
|
+
x.report("dry-initializer (with UNDEFINED)") do
|
51
|
+
DryTest.new
|
52
|
+
end
|
53
|
+
|
43
54
|
x.report("virtus") do
|
44
55
|
VirtusTest.new
|
45
56
|
end
|
data/dry-initializer.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = "dry-initializer"
|
3
|
-
gem.version = "
|
3
|
+
gem.version = "2.0.0"
|
4
4
|
gem.author = ["Vladimir Kochnev (marshall-lee)", "Andrew Kozin (nepalez)"]
|
5
|
-
gem.email =
|
5
|
+
gem.email = "andrew.kozin@gmail.com"
|
6
6
|
gem.homepage = "https://github.com/dryrb/dry-initializer"
|
7
7
|
gem.summary = "DSL for declaring params and options of the initializer"
|
8
8
|
gem.license = "MIT"
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.test_files = gem.files.grep(/^spec/)
|
12
12
|
gem.extra_rdoc_files = Dir["README.md", "LICENSE", "CHANGELOG.md"]
|
13
13
|
|
14
|
-
gem.required_ruby_version = ">= 2.
|
14
|
+
gem.required_ruby_version = ">= 2.3"
|
15
15
|
|
16
16
|
gem.add_development_dependency "rspec", "~> 3.0"
|
17
17
|
gem.add_development_dependency "rake", "> 10"
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Dry::Initializer::Builders
|
2
|
+
# @private
|
3
|
+
class Attribute
|
4
|
+
def self.[](definition)
|
5
|
+
new(definition).call
|
6
|
+
end
|
7
|
+
|
8
|
+
def call
|
9
|
+
lines.compact
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
# rubocop: disable Style/MethodLength
|
15
|
+
def initialize(definition)
|
16
|
+
@definition = definition
|
17
|
+
@option = definition.option
|
18
|
+
@type = definition.type
|
19
|
+
@optional = definition.optional
|
20
|
+
@default = definition.default
|
21
|
+
@source = definition.source
|
22
|
+
@ivar = definition.ivar
|
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
|
+
end
|
29
|
+
# rubocop: enable Style/MethodLength
|
30
|
+
|
31
|
+
def lines
|
32
|
+
[
|
33
|
+
"",
|
34
|
+
definition_line,
|
35
|
+
reader_line,
|
36
|
+
default_line,
|
37
|
+
coercion_line,
|
38
|
+
assignment_line
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
def reader_line
|
43
|
+
return unless @option
|
44
|
+
@optional ? optional_reader : required_reader
|
45
|
+
end
|
46
|
+
|
47
|
+
def optional_reader
|
48
|
+
"#{@val} = #{@opts}.fetch(:'#{@source}', #{@null})"
|
49
|
+
end
|
50
|
+
|
51
|
+
def required_reader
|
52
|
+
"#{@val} = #{@opts}.fetch(:'#{@source}')" \
|
53
|
+
" { raise KeyError, \"\#{self.class}: #{@definition} is required\" }"
|
54
|
+
end
|
55
|
+
|
56
|
+
def definition_line
|
57
|
+
return unless @type || @default
|
58
|
+
"#{@item} = __dry_initializer_config__.definitions[:'#{@source}']"
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_line
|
62
|
+
return unless @default
|
63
|
+
"#{@val} = instance_exec(&#{@item}.default) if #{@val} == #{@null}"
|
64
|
+
end
|
65
|
+
|
66
|
+
def coercion_line
|
67
|
+
return unless @type
|
68
|
+
"#{@val} = #{@item}.type.call(#{@val}) unless #{@val} == #{@null}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def assignment_line
|
72
|
+
"#{@ivar} = #{@val}" \
|
73
|
+
" unless #{@val} == #{@null} && instance_variable_defined?(:#{@ivar})"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Dry::Initializer::Builders
|
2
|
+
# @private
|
3
|
+
class Initializer
|
4
|
+
require_relative "signature"
|
5
|
+
require_relative "attribute"
|
6
|
+
|
7
|
+
def self.[](config)
|
8
|
+
new(config).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def call
|
12
|
+
lines.flatten.compact.join("\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def initialize(config)
|
18
|
+
@config = config
|
19
|
+
@definitions = config.definitions.values
|
20
|
+
end
|
21
|
+
|
22
|
+
def lines
|
23
|
+
[
|
24
|
+
undef_line,
|
25
|
+
define_line,
|
26
|
+
params_lines,
|
27
|
+
options_lines,
|
28
|
+
end_line
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
def undef_line
|
33
|
+
"undef :__dry_initializer_initialize__" \
|
34
|
+
" if private_method_defined? :__dry_initializer_initialize__"
|
35
|
+
end
|
36
|
+
|
37
|
+
def define_line
|
38
|
+
"private def __dry_initializer_initialize__(#{Signature[@config]})"
|
39
|
+
end
|
40
|
+
|
41
|
+
def params_lines
|
42
|
+
@definitions.reject(&:option)
|
43
|
+
.flat_map { |item| Attribute[item] }
|
44
|
+
.map { |line| " " << line }
|
45
|
+
end
|
46
|
+
|
47
|
+
def options_lines
|
48
|
+
@definitions.select(&:option)
|
49
|
+
.flat_map { |item| Attribute[item] }
|
50
|
+
.map { |line| " " << line }
|
51
|
+
end
|
52
|
+
|
53
|
+
def end_line
|
54
|
+
"end"
|
55
|
+
end
|
56
|
+
|
57
|
+
def private_line
|
58
|
+
"private :__dry_initializer_initialize__"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Dry::Initializer::Builders
|
2
|
+
# @private
|
3
|
+
class Reader
|
4
|
+
def self.[](definition)
|
5
|
+
new(definition).call
|
6
|
+
end
|
7
|
+
|
8
|
+
def call
|
9
|
+
lines.flatten.compact.join("\n")
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def initialize(definition)
|
15
|
+
@target = definition.target
|
16
|
+
@ivar = definition.ivar
|
17
|
+
@null = definition.null
|
18
|
+
@reader = definition.reader
|
19
|
+
end
|
20
|
+
|
21
|
+
def lines
|
22
|
+
[undef_line, attribute_line, method_lines, type_line]
|
23
|
+
end
|
24
|
+
|
25
|
+
def undef_line
|
26
|
+
"undef :#{@target} if method_defined?(:#{@target})" \
|
27
|
+
" || private_method_defined?(:#{@target})" \
|
28
|
+
" || protected_method_defined?(:#{@target})"
|
29
|
+
end
|
30
|
+
|
31
|
+
def attribute_line
|
32
|
+
return unless @reader
|
33
|
+
"attr_reader :#{@target}" unless @null
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_lines
|
37
|
+
return unless @reader
|
38
|
+
return unless @null
|
39
|
+
[
|
40
|
+
"def #{@target}",
|
41
|
+
" #{@ivar} unless #{@ivar} == Dry::Initializer::UNDEFINED",
|
42
|
+
"end"
|
43
|
+
]
|
44
|
+
end
|
45
|
+
|
46
|
+
def type_line
|
47
|
+
"#{@reader} :#{@target}" if %i[private protected].include? @reader
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Dry::Initializer::Builders
|
2
|
+
# @private
|
3
|
+
class Signature
|
4
|
+
def self.[](config)
|
5
|
+
new(config).call
|
6
|
+
end
|
7
|
+
|
8
|
+
def call
|
9
|
+
[*required_params, *optional_params, "*", options].compact.join(", ")
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def initialize(config)
|
15
|
+
@config = config
|
16
|
+
@options = config.options.any?
|
17
|
+
@null = config.null ? "Dry::Initializer::UNDEFINED" : "nil"
|
18
|
+
end
|
19
|
+
|
20
|
+
def required_params
|
21
|
+
@config.params.reject(&:optional).map(&:source)
|
22
|
+
end
|
23
|
+
|
24
|
+
def optional_params
|
25
|
+
@config.params.select(&:optional).map { |rec| "#{rec.source} = #{@null}" }
|
26
|
+
end
|
27
|
+
|
28
|
+
def options
|
29
|
+
"**__dry_initializer_options__" if @options
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|