dry-initializer 3.0.4 → 3.1.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 +4 -4
- data/CHANGELOG.md +21 -0
- data/LICENSE +1 -1
- data/README.md +4 -3
- data/dry-initializer.gemspec +15 -13
- data/lib/dry/initializer/builders/attribute.rb +86 -82
- data/lib/dry/initializer/builders/initializer.rb +56 -54
- data/lib/dry/initializer/builders/reader.rb +55 -49
- data/lib/dry/initializer/builders/signature.rb +29 -23
- data/lib/dry/initializer/builders.rb +9 -5
- data/lib/dry/initializer/config.rb +160 -158
- data/lib/dry/initializer/definition.rb +58 -54
- data/lib/dry/initializer/dispatchers/build_nested_type.rb +54 -40
- data/lib/dry/initializer/dispatchers/check_type.rb +45 -39
- data/lib/dry/initializer/dispatchers/prepare_default.rb +32 -25
- data/lib/dry/initializer/dispatchers/prepare_ivar.rb +13 -6
- data/lib/dry/initializer/dispatchers/prepare_optional.rb +14 -7
- data/lib/dry/initializer/dispatchers/prepare_reader.rb +29 -22
- data/lib/dry/initializer/dispatchers/prepare_source.rb +12 -5
- data/lib/dry/initializer/dispatchers/prepare_target.rb +44 -37
- data/lib/dry/initializer/dispatchers/unwrap_type.rb +21 -10
- data/lib/dry/initializer/dispatchers/wrap_type.rb +24 -17
- data/lib/dry/initializer/dispatchers.rb +48 -43
- data/lib/dry/initializer/dsl.rb +42 -34
- data/lib/dry/initializer/mixin/local.rb +19 -13
- data/lib/dry/initializer/mixin/root.rb +12 -7
- data/lib/dry/initializer/mixin.rb +17 -12
- data/lib/dry/initializer/struct.rb +34 -29
- data/lib/dry/initializer/undefined.rb +7 -1
- data/lib/dry/initializer/version.rb +3 -1
- data/lib/dry/initializer.rb +11 -9
- data/lib/dry-initializer.rb +3 -1
- data/lib/tasks/benchmark.rake +15 -13
- data/lib/tasks/profile.rake +20 -16
- metadata +4 -4
data/lib/dry/initializer/dsl.rb
CHANGED
@@ -1,43 +1,51 @@
|
|
1
|
-
|
2
|
-
# Module-level DSL
|
3
|
-
module DSL
|
4
|
-
# Setting for null (undefined value)
|
5
|
-
# @return [nil, Dry::Initializer::UNDEFINED]
|
6
|
-
attr_reader :null
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
8
|
-
|
9
|
-
|
10
|
-
#
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
# Module-level DSL
|
6
|
+
module DSL
|
7
|
+
# Setting for null (undefined value)
|
8
|
+
# @return [nil, Dry::Initializer::UNDEFINED]
|
9
|
+
attr_reader :null
|
10
|
+
|
11
|
+
# Returns a version of the module with custom settings
|
12
|
+
# @option settings [Boolean] :undefined
|
13
|
+
# If unassigned params and options should be treated different from nil
|
14
|
+
# @return [Dry::Initializer]
|
15
|
+
def [](undefined: true, **)
|
16
|
+
null = undefined == false ? nil : UNDEFINED
|
17
|
+
Module.new.tap do |mod|
|
18
|
+
mod.extend DSL
|
19
|
+
mod.include self
|
20
|
+
mod.send(:instance_variable_set, :@null, null)
|
21
|
+
end
|
18
22
|
end
|
19
|
-
end
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
24
|
+
# Returns mixin module to be included to target class by hand
|
25
|
+
# @return [Module]
|
26
|
+
# @yield proc defining params and options
|
27
|
+
def define(procedure = nil, &block)
|
28
|
+
config = Config.new(null: null)
|
29
|
+
config.instance_exec(&(procedure || block))
|
30
|
+
config.mixin.include Mixin::Root
|
31
|
+
config.mixin
|
32
|
+
end
|
30
33
|
|
31
|
-
|
34
|
+
private
|
32
35
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
def extended(klass)
|
37
|
+
config = Config.new(klass, null: null)
|
38
|
+
klass.send :instance_variable_set, :@dry_initializer, config
|
39
|
+
klass.include Mixin::Root
|
40
|
+
end
|
38
41
|
|
39
|
-
|
40
|
-
|
42
|
+
class << self
|
43
|
+
private
|
44
|
+
|
45
|
+
def extended(mod)
|
46
|
+
mod.instance_variable_set :@null, UNDEFINED
|
47
|
+
end
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
43
51
|
end
|
@@ -1,19 +1,25 @@
|
|
1
|
-
|
2
|
-
# @private
|
3
|
-
module Local
|
4
|
-
attr_reader :klass
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
module Mixin
|
6
|
+
# @private
|
7
|
+
module Local
|
8
|
+
attr_reader :klass
|
9
|
+
|
10
|
+
def inspect
|
11
|
+
"Dry::Initializer::Mixin::Local[#{klass}]"
|
12
|
+
end
|
13
|
+
alias_method :to_s, :inspect
|
14
|
+
alias_method :to_str, :inspect
|
11
15
|
|
12
|
-
|
16
|
+
private
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
|
18
|
+
def included(klass)
|
19
|
+
@klass = klass
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
17
23
|
end
|
18
24
|
end
|
19
25
|
end
|
@@ -1,11 +1,16 @@
|
|
1
|
-
|
2
|
-
# @private
|
3
|
-
module Root
|
4
|
-
private
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
7
|
-
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
module Mixin
|
6
|
+
# @private
|
7
|
+
module Root
|
8
|
+
private
|
9
|
+
|
10
|
+
def initialize(...)
|
11
|
+
__dry_initializer_initialize__(...)
|
12
|
+
end
|
13
|
+
end
|
8
14
|
end
|
9
|
-
ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true)
|
10
15
|
end
|
11
16
|
end
|
@@ -1,15 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Dry
|
4
|
+
module Initializer
|
5
|
+
# @private
|
6
|
+
module Mixin
|
7
|
+
extend DSL # @deprecated
|
8
|
+
include Dry::Initializer # @deprecated
|
9
|
+
# @deprecated
|
10
|
+
def self.extended(klass)
|
11
|
+
warn "[DEPRECATED] Use Dry::Initializer instead of its alias" \
|
12
|
+
" Dry::Initializer::Mixin. The later will be removed in v2.1.0"
|
13
|
+
super
|
14
|
+
end
|
11
15
|
|
12
|
-
|
13
|
-
|
16
|
+
require_relative "mixin/root"
|
17
|
+
require_relative "mixin/local"
|
18
|
+
end
|
14
19
|
end
|
15
20
|
end
|
@@ -1,39 +1,44 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# The nested structure that takes nested hashes with indifferent access
|
3
4
|
#
|
4
|
-
|
5
|
-
|
5
|
+
module Dry
|
6
|
+
module Initializer
|
7
|
+
class Struct
|
8
|
+
extend ::Dry::Initializer
|
6
9
|
|
7
|
-
|
8
|
-
|
10
|
+
class << self
|
11
|
+
undef_method :param
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
def new(options)
|
14
|
+
super(**Hash(options).each_with_object({}) { |(k, v), h| h[k.to_sym] = v })
|
15
|
+
end
|
16
|
+
alias_method :call, :new
|
17
|
+
end
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
#
|
20
|
+
# Represents event data as a nested hash with deeply stringified keys
|
21
|
+
# @return [Hash<String, ...>]
|
22
|
+
#
|
23
|
+
def to_h
|
24
|
+
self
|
25
|
+
.class
|
26
|
+
.dry_initializer
|
27
|
+
.attributes(self)
|
28
|
+
.each_with_object({}) { |(k, v), h| h[k.to_s] = __hashify(v) }
|
29
|
+
end
|
27
30
|
|
28
|
-
|
31
|
+
private
|
29
32
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
def __hashify(value)
|
34
|
+
case value
|
35
|
+
when Hash
|
36
|
+
value.each_with_object({}) { |(k, v), obj| obj[k.to_s] = __hashify(v) }
|
37
|
+
when Array then value.map { |v| __hashify(v) }
|
38
|
+
when Dry::Initializer::Struct then value.to_h
|
39
|
+
else value
|
40
|
+
end
|
41
|
+
end
|
37
42
|
end
|
38
43
|
end
|
39
44
|
end
|
data/lib/dry/initializer.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
2
4
|
|
3
5
|
# Namespace for gems in a dry-rb community
|
4
6
|
module Dry
|
@@ -6,13 +8,13 @@ module Dry
|
|
6
8
|
# DSL for declaring params and options of class initializers
|
7
9
|
#
|
8
10
|
module Initializer
|
9
|
-
require_relative
|
10
|
-
require_relative
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
14
|
-
require_relative
|
15
|
-
require_relative
|
11
|
+
require_relative "initializer/undefined"
|
12
|
+
require_relative "initializer/dsl"
|
13
|
+
require_relative "initializer/definition"
|
14
|
+
require_relative "initializer/builders"
|
15
|
+
require_relative "initializer/config"
|
16
|
+
require_relative "initializer/mixin"
|
17
|
+
require_relative "initializer/dispatchers"
|
16
18
|
|
17
19
|
# Adds methods [.[]] and [.define]
|
18
20
|
extend DSL
|
@@ -56,6 +58,6 @@ module Dry
|
|
56
58
|
dry_initializer.children << config
|
57
59
|
end
|
58
60
|
|
59
|
-
require_relative
|
61
|
+
require_relative "initializer/struct"
|
60
62
|
end
|
61
63
|
end
|
data/lib/dry-initializer.rb
CHANGED
data/lib/tasks/benchmark.rake
CHANGED
@@ -1,36 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
namespace :benchmark do
|
2
|
-
desc
|
4
|
+
desc "Runs benchmarks for plain params"
|
3
5
|
task :plain_params do
|
4
|
-
system
|
6
|
+
system "ruby benchmarks/plain_params.rb"
|
5
7
|
end
|
6
8
|
|
7
|
-
desc
|
9
|
+
desc "Runs benchmarks for plain options"
|
8
10
|
task :plain_options do
|
9
|
-
system
|
11
|
+
system "ruby benchmarks/plain_options.rb"
|
10
12
|
end
|
11
13
|
|
12
|
-
desc
|
14
|
+
desc "Runs benchmarks for value coercion"
|
13
15
|
task :with_coercion do
|
14
|
-
system
|
16
|
+
system "ruby benchmarks/with_coercion.rb"
|
15
17
|
end
|
16
18
|
|
17
|
-
desc
|
19
|
+
desc "Runs benchmarks with defaults"
|
18
20
|
task :with_defaults do
|
19
|
-
system
|
21
|
+
system "ruby benchmarks/with_defaults.rb"
|
20
22
|
end
|
21
23
|
|
22
|
-
desc
|
24
|
+
desc "Runs benchmarks with defaults and coercion"
|
23
25
|
task :with_defaults_and_coercion do
|
24
|
-
system
|
26
|
+
system "ruby benchmarks/with_defaults_and_coercion.rb"
|
25
27
|
end
|
26
28
|
|
27
|
-
desc
|
29
|
+
desc "Runs benchmarks for several defaults"
|
28
30
|
task :compare_several_defaults do
|
29
|
-
system
|
31
|
+
system "ruby benchmarks/with_several_defaults.rb"
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
desc
|
35
|
+
desc "Runs all benchmarks"
|
34
36
|
task benchmark: %i[
|
35
37
|
benchmark:plain_params
|
36
38
|
benchmark:plain_options
|
data/lib/tasks/profile.rake
CHANGED
@@ -1,32 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop: disable Lint/ConstantDefinitionInBlock
|
1
4
|
namespace :profile do
|
2
5
|
def profile(name, execution, &definition)
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
+
require "dry-initializer"
|
7
|
+
require "ruby-prof"
|
8
|
+
require "fileutils"
|
6
9
|
|
7
10
|
definition.call
|
8
11
|
result = RubyProf.profile do
|
9
12
|
1_000.times { execution.call }
|
10
13
|
end
|
11
14
|
|
12
|
-
FileUtils.mkdir_p
|
15
|
+
FileUtils.mkdir_p "./tmp"
|
13
16
|
|
14
17
|
FileUtils.touch "./tmp/#{name}.dot"
|
15
|
-
File.open("./tmp/#{name}.dot",
|
18
|
+
File.open("./tmp/#{name}.dot", "w+") do |output|
|
16
19
|
RubyProf::DotPrinter.new(result).print(output, min_percent: 0)
|
17
20
|
end
|
18
21
|
|
19
22
|
FileUtils.touch "./tmp/#{name}.html"
|
20
|
-
File.open("./tmp/#{name}.html",
|
23
|
+
File.open("./tmp/#{name}.html", "w+") do |output|
|
21
24
|
RubyProf::CallStackPrinter.new(result).print(output, min_percent: 0)
|
22
25
|
end
|
23
26
|
|
24
27
|
system "dot -Tpng ./tmp/#{name}.dot > ./tmp/#{name}.png"
|
25
28
|
end
|
26
29
|
|
27
|
-
desc
|
30
|
+
desc "Profiles initialization with required param and option"
|
28
31
|
task :required do
|
29
|
-
profile(
|
32
|
+
profile("required", -> { User.new :Andy, email: "andy@example.com" }) do
|
30
33
|
class User
|
31
34
|
extend Dry::Initializer
|
32
35
|
param :name
|
@@ -35,20 +38,20 @@ namespace :profile do
|
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
38
|
-
desc
|
41
|
+
desc "Profiles initialization with default param and option"
|
39
42
|
task :defaults do
|
40
|
-
profile(
|
43
|
+
profile("defaults", -> { User.new }) do
|
41
44
|
class User
|
42
45
|
extend Dry::Initializer
|
43
46
|
param :name, default: -> { :Andy }
|
44
|
-
option :email, default: -> {
|
47
|
+
option :email, default: -> { "andy@example.com" }
|
45
48
|
end
|
46
49
|
end
|
47
50
|
end
|
48
51
|
|
49
|
-
desc
|
52
|
+
desc "Profiles initialization with coerced param and option"
|
50
53
|
task :coercion do
|
51
|
-
profile(
|
54
|
+
profile("coercion", -> { User.new :Andy, email: :"andy@example.com" }) do
|
52
55
|
class User
|
53
56
|
extend Dry::Initializer
|
54
57
|
param :name, proc(&:to_s)
|
@@ -57,9 +60,9 @@ namespace :profile do
|
|
57
60
|
end
|
58
61
|
end
|
59
62
|
|
60
|
-
desc
|
63
|
+
desc "Profiles initialization with coerced defaults of param and option"
|
61
64
|
task :default_coercion do
|
62
|
-
profile(
|
65
|
+
profile("default_coercion", -> { User.new }) do
|
63
66
|
class User
|
64
67
|
extend Dry::Initializer
|
65
68
|
param :name, proc(&:to_s), default: -> { :Andy }
|
@@ -69,10 +72,11 @@ namespace :profile do
|
|
69
72
|
end
|
70
73
|
end
|
71
74
|
|
72
|
-
desc
|
75
|
+
desc "Makes all profiling at once"
|
73
76
|
task profile: %i[
|
74
77
|
profile:required
|
75
78
|
profile:defaults
|
76
79
|
profile:coercion
|
77
80
|
profile:default_coercion
|
78
81
|
]
|
82
|
+
# rubocop: enable Lint/ConstantDefinitionInBlock
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-initializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vladimir Kochnev (marshall-lee)
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-01-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -95,14 +95,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
95
|
requirements:
|
96
96
|
- - ">="
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version: 2.
|
98
|
+
version: 2.7.0
|
99
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
requirements: []
|
105
|
-
rubygems_version: 3.
|
105
|
+
rubygems_version: 3.1.6
|
106
106
|
signing_key:
|
107
107
|
specification_version: 4
|
108
108
|
summary: DSL for declaring params and options of the initializer
|