smart_initializer 0.7.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/CHANGELOG.md +46 -3
- data/Gemfile.lock +40 -39
- data/README.md +286 -41
- data/bin/console +2 -2
- data/gemfiles/with_external_deps.gemfile.lock +40 -39
- data/gemfiles/without_external_deps.gemfile.lock +39 -40
- data/lib/smart_core/initializer/attribute/factory/base.rb +154 -0
- data/lib/smart_core/initializer/attribute/factory/option.rb +107 -0
- data/lib/smart_core/initializer/attribute/factory/param.rb +63 -0
- data/lib/smart_core/initializer/attribute/factory.rb +5 -199
- data/lib/smart_core/initializer/attribute/finalizer/abstract.rb +2 -0
- data/lib/smart_core/initializer/attribute/finalizer/instance_method.rb +1 -1
- data/lib/smart_core/initializer/attribute/finalizer.rb +5 -5
- data/lib/smart_core/initializer/attribute/list.rb +20 -0
- data/lib/smart_core/initializer/attribute/{parameters.rb → value/base.rb} +35 -65
- data/lib/smart_core/initializer/attribute/value/option.rb +101 -0
- data/lib/smart_core/initializer/attribute/value/param.rb +24 -0
- data/lib/smart_core/initializer/attribute/value.rb +9 -0
- data/lib/smart_core/initializer/attribute.rb +3 -125
- data/lib/smart_core/initializer/configuration.rb +7 -3
- data/lib/smart_core/initializer/constructor/definer.rb +135 -46
- data/lib/smart_core/initializer/constructor.rb +28 -14
- data/lib/smart_core/initializer/dsl.rb +38 -24
- data/lib/smart_core/initializer/errors.rb +20 -4
- data/lib/smart_core/initializer/functionality.rb +7 -8
- data/lib/smart_core/initializer/settings/auto_cast.rb +40 -0
- data/lib/smart_core/initializer/settings/base.rb +49 -0
- data/lib/smart_core/initializer/settings/duplicator.rb +5 -0
- data/lib/smart_core/initializer/settings/strict_options.rb +40 -0
- data/lib/smart_core/initializer/settings/type_system.rb +10 -28
- data/lib/smart_core/initializer/settings.rb +40 -0
- data/lib/smart_core/initializer/type_system/registry.rb +2 -1
- data/lib/smart_core/initializer/type_system/smart_types.rb +2 -2
- data/lib/smart_core/initializer/version.rb +2 -2
- data/lib/smart_core/initializer.rb +14 -4
- data/smart_initializer.gemspec +2 -2
- metadata +16 -7
@@ -2,132 +2,10 @@
|
|
2
2
|
|
3
3
|
# @api private
|
4
4
|
# @since 0.1.0
|
5
|
-
|
6
|
-
|
5
|
+
# @version 0.8.0
|
6
|
+
module SmartCore::Initializer::Attribute
|
7
|
+
require_relative 'attribute/value'
|
7
8
|
require_relative 'attribute/list'
|
8
9
|
require_relative 'attribute/finalizer'
|
9
10
|
require_relative 'attribute/factory'
|
10
|
-
|
11
|
-
# @since 0.1.0
|
12
|
-
extend ::Forwardable
|
13
|
-
|
14
|
-
# @return [Symbol]
|
15
|
-
#
|
16
|
-
# @pai private
|
17
|
-
# @since 0.1.0
|
18
|
-
def_delegator :parameters, :name
|
19
|
-
|
20
|
-
# @return [SmartCore::Initializer::TypeSystem::Interop]
|
21
|
-
#
|
22
|
-
# @pai private
|
23
|
-
# @since 0.1.0
|
24
|
-
def_delegator :parameters, :type
|
25
|
-
|
26
|
-
# @return [Class<SmartCore::Initializer::TypeSystem::Interop>]
|
27
|
-
#
|
28
|
-
# @api private
|
29
|
-
# @since 0.1.0
|
30
|
-
def_delegator :parameters, :type_system
|
31
|
-
|
32
|
-
# @return [Symbol]
|
33
|
-
#
|
34
|
-
# @pai private
|
35
|
-
# @since 0.1.0
|
36
|
-
def_delegator :parameters, :privacy
|
37
|
-
|
38
|
-
# @return [SmartCore::Initializer::Attribute::Finalizer::AnonymousBlock/InstanceMethod]
|
39
|
-
#
|
40
|
-
# @pai private
|
41
|
-
# @since 0.1.0
|
42
|
-
def_delegator :parameters, :finalizer
|
43
|
-
|
44
|
-
# @return [Boolean]
|
45
|
-
#
|
46
|
-
# @pai private
|
47
|
-
# @since 0.1.0
|
48
|
-
def_delegators :parameters, :cast, :cast?
|
49
|
-
|
50
|
-
# @return [Any]
|
51
|
-
#
|
52
|
-
# @api private
|
53
|
-
# @since 0.1.0
|
54
|
-
def_delegator :parameters, :default
|
55
|
-
|
56
|
-
# @return [Boolean]
|
57
|
-
#
|
58
|
-
# @api private
|
59
|
-
# @since 0.1.0
|
60
|
-
def_delegator :parameters, :has_default?
|
61
|
-
|
62
|
-
# @return [Boolean]
|
63
|
-
#
|
64
|
-
# @api private
|
65
|
-
# @since 0.4.0
|
66
|
-
def_delegator :parameters, :read_only
|
67
|
-
|
68
|
-
# @return [String, Symbol, NilClass]
|
69
|
-
#
|
70
|
-
# @api private
|
71
|
-
# @since 0.4.0
|
72
|
-
def_delegator :parameters, :as
|
73
|
-
|
74
|
-
# @param name [Symbol]
|
75
|
-
# @param type [SmartCore::Initializer::TypeSystem::Interop]
|
76
|
-
# @param type_system [Class<SmartCore::Initializer::TypeSystem::Interop>]
|
77
|
-
# @param privacy [Symbol]
|
78
|
-
# @param finalizer [SmartCore::Initializer::Attribute::Finalizer::AnonymousBlock/InstanceMethod]
|
79
|
-
# @param cast [Boolean]
|
80
|
-
# @param read_only [Boolean]
|
81
|
-
# @param as [String, Symbol, NilClass]
|
82
|
-
# @param dynamic_options [Hash<Symbol,Any>]
|
83
|
-
# @return [void]
|
84
|
-
#
|
85
|
-
# @api private
|
86
|
-
# @since 0.1.0
|
87
|
-
def initialize(name, type, type_system, privacy, finalizer, cast, read_only, as, dynamic_options)
|
88
|
-
@parameters = SmartCore::Initializer::Attribute::Parameters.new(
|
89
|
-
name, type, type_system, privacy, finalizer, cast, read_only, as, dynamic_options
|
90
|
-
)
|
91
|
-
end
|
92
|
-
|
93
|
-
# @param value [Any]
|
94
|
-
# @return [void]
|
95
|
-
#
|
96
|
-
# @api private
|
97
|
-
# @since 0.5.1
|
98
|
-
def validate!(value)
|
99
|
-
type.validate!(value)
|
100
|
-
rescue => error
|
101
|
-
raise SmartCore::Initializer::IncorrectTypeError,
|
102
|
-
"Validation of attribute '#{name}' (#{type.identifier}, got #{value.class}) failed: " \
|
103
|
-
"#{error.message}"
|
104
|
-
end
|
105
|
-
|
106
|
-
# @return [SmartCore::Initializer::Attribute]
|
107
|
-
#
|
108
|
-
# @api private
|
109
|
-
# @since 0.1.0
|
110
|
-
# rubocop:disable Metrics/AbcSize
|
111
|
-
def dup
|
112
|
-
self.class.new(
|
113
|
-
parameters.name.dup,
|
114
|
-
parameters.type,
|
115
|
-
parameters.type_system,
|
116
|
-
parameters.privacy,
|
117
|
-
parameters.finalizer.dup,
|
118
|
-
parameters.cast,
|
119
|
-
parameters.read_only,
|
120
|
-
parameters.as,
|
121
|
-
parameters.dynamic_options.dup
|
122
|
-
)
|
123
|
-
end
|
124
|
-
# rubocop:enable Metrics/AbcSize
|
125
|
-
|
126
|
-
private
|
127
|
-
|
128
|
-
# @return [SmartCore::Initializer::Attribute::Parameters]
|
129
|
-
#
|
130
|
-
# @api private
|
131
|
-
# @since 0.1.0
|
132
|
-
attr_reader :parameters
|
133
11
|
end
|
@@ -25,14 +25,18 @@ module SmartCore::Initializer::Configuration
|
|
25
25
|
|
26
26
|
# @since 0.1.0
|
27
27
|
configuration do
|
28
|
+
# @since 0.?.0
|
28
29
|
setting :default_type_system, :smart_types
|
29
30
|
validate :default_type_system do |value|
|
30
31
|
SmartCore::Initializer::TypeSystem.resolve(value) rescue false
|
31
32
|
end
|
32
33
|
|
34
|
+
# @since 0.?.0
|
33
35
|
setting :strict_options, true
|
34
|
-
validate :strict_options
|
35
|
-
|
36
|
-
|
36
|
+
validate :strict_options, :boolean
|
37
|
+
|
38
|
+
# @since 0.8.0
|
39
|
+
setting :auto_cast, false
|
40
|
+
validate :auto_cast, :boolean
|
37
41
|
end
|
38
42
|
end
|
@@ -31,13 +31,13 @@ class SmartCore::Initializer::Constructor::Definer
|
|
31
31
|
# @param privacy [String, Symbol]
|
32
32
|
# @param finalize [String, Symbol, Proc]
|
33
33
|
# @param cast [Boolean]
|
34
|
-
# @param
|
34
|
+
# @param mutable [Boolean]
|
35
35
|
# @param as [String, Symbol, NilClass]
|
36
|
-
# @param dynamic_options [Hash<Symbol,Any>]
|
37
36
|
# @return [void]
|
38
37
|
#
|
39
38
|
# @api private
|
40
39
|
# @since 0.1.0
|
40
|
+
# @version 0.8.0
|
41
41
|
def define_parameter(
|
42
42
|
name,
|
43
43
|
type,
|
@@ -45,21 +45,19 @@ class SmartCore::Initializer::Constructor::Definer
|
|
45
45
|
privacy,
|
46
46
|
finalize,
|
47
47
|
cast,
|
48
|
-
|
49
|
-
as
|
50
|
-
dynamic_options
|
48
|
+
mutable,
|
49
|
+
as
|
51
50
|
)
|
52
51
|
thread_safe do
|
53
|
-
attribute =
|
52
|
+
attribute = build_param_attribute(
|
54
53
|
name,
|
55
54
|
type,
|
56
55
|
type_system,
|
57
56
|
privacy,
|
58
57
|
finalize,
|
59
58
|
cast,
|
60
|
-
|
61
|
-
as
|
62
|
-
dynamic_options
|
59
|
+
mutable,
|
60
|
+
as
|
63
61
|
)
|
64
62
|
prevent_option_overlap(attribute)
|
65
63
|
add_parameter(attribute)
|
@@ -67,23 +65,25 @@ class SmartCore::Initializer::Constructor::Definer
|
|
67
65
|
end
|
68
66
|
|
69
67
|
# @param names [Array<String, Symbol>]
|
68
|
+
# @option mutable [Boolean]
|
69
|
+
# @option privacy [String, Symbol]
|
70
70
|
# @return [void]
|
71
71
|
#
|
72
72
|
# @api private
|
73
73
|
# @since 0.1.0
|
74
|
-
|
74
|
+
# @version 0.8.0
|
75
|
+
def define_parameters(*names, mutable:, privacy:)
|
75
76
|
thread_safe do
|
76
77
|
names.map do |name|
|
77
|
-
|
78
|
+
build_param_attribute(
|
78
79
|
name,
|
79
80
|
klass.__initializer_settings__.generic_type_object,
|
80
81
|
klass.__initializer_settings__.type_system,
|
81
|
-
|
82
|
-
SmartCore::Initializer::Attribute::
|
83
|
-
|
84
|
-
|
85
|
-
SmartCore::Initializer::Attribute::
|
86
|
-
SmartCore::Initializer::Attribute::Parameters::DEFAULT_DYNAMIC_OPTIONS.dup
|
82
|
+
privacy,
|
83
|
+
SmartCore::Initializer::Attribute::Value::Param::DEFAULT_FINALIZER,
|
84
|
+
klass.__initializer_settings__.auto_cast,
|
85
|
+
mutable,
|
86
|
+
SmartCore::Initializer::Attribute::Value::Param::DEFAULT_AS
|
87
87
|
).tap do |attribute|
|
88
88
|
prevent_option_overlap(attribute)
|
89
89
|
end
|
@@ -99,13 +99,15 @@ class SmartCore::Initializer::Constructor::Definer
|
|
99
99
|
# @param privacy [String, Symbol]
|
100
100
|
# @param finalize [String, Symbol, Proc]
|
101
101
|
# @param cast [Boolean]
|
102
|
-
# @param
|
102
|
+
# @param mutable [Boolean]
|
103
103
|
# @param as [String, Symbol, NilClass]
|
104
|
-
# @param
|
104
|
+
# @param default [Proc, Any]
|
105
|
+
# @param optional [Boolean]
|
105
106
|
# @return [void]
|
106
107
|
#
|
107
108
|
# @api private
|
108
109
|
# @since 0.1.0
|
110
|
+
# @version 0.8.0
|
109
111
|
def define_option(
|
110
112
|
name,
|
111
113
|
type,
|
@@ -113,21 +115,23 @@ class SmartCore::Initializer::Constructor::Definer
|
|
113
115
|
privacy,
|
114
116
|
finalize,
|
115
117
|
cast,
|
116
|
-
|
118
|
+
mutable,
|
117
119
|
as,
|
118
|
-
|
120
|
+
default,
|
121
|
+
optional
|
119
122
|
)
|
120
123
|
thread_safe do
|
121
|
-
attribute =
|
124
|
+
attribute = build_option_attribute(
|
122
125
|
name,
|
123
126
|
type,
|
124
127
|
type_system,
|
125
128
|
privacy,
|
126
129
|
finalize,
|
127
130
|
cast,
|
128
|
-
|
131
|
+
mutable,
|
129
132
|
as,
|
130
|
-
|
133
|
+
default,
|
134
|
+
optional
|
131
135
|
)
|
132
136
|
prevent_parameter_overlap(attribute)
|
133
137
|
add_option(attribute)
|
@@ -135,23 +139,27 @@ class SmartCore::Initializer::Constructor::Definer
|
|
135
139
|
end
|
136
140
|
|
137
141
|
# @param names [Array<String, Symbol>]
|
142
|
+
# @option mutable [Boolean]
|
143
|
+
# @option privacy [String, Symbol]
|
138
144
|
# @return [void]
|
139
145
|
#
|
140
146
|
# @api private
|
141
147
|
# @since 0.1.0
|
142
|
-
|
148
|
+
# @version 0.8.0
|
149
|
+
def define_options(*names, mutable:, privacy:)
|
143
150
|
thread_safe do
|
144
151
|
names.map do |name|
|
145
|
-
|
152
|
+
build_option_attribute(
|
146
153
|
name,
|
147
154
|
klass.__initializer_settings__.generic_type_object,
|
148
155
|
klass.__initializer_settings__.type_system,
|
149
|
-
|
150
|
-
SmartCore::Initializer::Attribute::
|
151
|
-
|
152
|
-
|
153
|
-
SmartCore::Initializer::Attribute::
|
154
|
-
SmartCore::Initializer::Attribute::
|
156
|
+
privacy,
|
157
|
+
SmartCore::Initializer::Attribute::Value::Option::DEFAULT_FINALIZER,
|
158
|
+
klass.__initializer_settings__.auto_cast,
|
159
|
+
mutable,
|
160
|
+
SmartCore::Initializer::Attribute::Value::Option::DEFAULT_AS,
|
161
|
+
SmartCore::Initializer::Attribute::Value::Option::UNDEFINED_DEFAULT,
|
162
|
+
SmartCore::Initializer::Attribute::Value::Option::DEFAULT_OPTIONAL
|
155
163
|
).tap do |attribute|
|
156
164
|
prevent_parameter_overlap(attribute)
|
157
165
|
end
|
@@ -175,26 +183,57 @@ class SmartCore::Initializer::Constructor::Definer
|
|
175
183
|
# @param privacy [String, Symbol]
|
176
184
|
# @param finalize [String, Symbol, Proc]
|
177
185
|
# @param cast [Boolean]
|
178
|
-
# @param
|
186
|
+
# @param mutable [Boolean]
|
187
|
+
# @param as [String, Symbol, NilClass]
|
188
|
+
# @return [SmartCore::Initializer::Attribute::Value::Param]
|
189
|
+
#
|
190
|
+
# @api private
|
191
|
+
# @since 0.1.0
|
192
|
+
# @version 0.8.0
|
193
|
+
def build_param_attribute(
|
194
|
+
name,
|
195
|
+
type,
|
196
|
+
type_system,
|
197
|
+
privacy,
|
198
|
+
finalize,
|
199
|
+
cast,
|
200
|
+
mutable,
|
201
|
+
as
|
202
|
+
)
|
203
|
+
SmartCore::Initializer::Attribute::Factory::Param.create(
|
204
|
+
name, type, type_system, privacy, finalize, cast, mutable, as
|
205
|
+
)
|
206
|
+
end
|
207
|
+
|
208
|
+
# @param name [String, Symbol]
|
209
|
+
# @param type [String, Symbol, Any]
|
210
|
+
# @param type_system [String, Symbol]
|
211
|
+
# @param privacy [String, Symbol]
|
212
|
+
# @param finalize [String, Symbol, Proc]
|
213
|
+
# @param cast [Boolean]
|
214
|
+
# @param mutable [Boolean]
|
179
215
|
# @param as [String, Symbol, NilClass]
|
180
|
-
# @param
|
181
|
-
# @
|
216
|
+
# @param default [Proc, Any]
|
217
|
+
# @param optional [Boolean]
|
218
|
+
# @return [SmartCore::Initializer::Attribute::Value::Option]
|
182
219
|
#
|
183
220
|
# @api private
|
184
221
|
# @since 0.1.0
|
185
|
-
|
222
|
+
# @version 0.8.0
|
223
|
+
def build_option_attribute(
|
186
224
|
name,
|
187
225
|
type,
|
188
226
|
type_system,
|
189
227
|
privacy,
|
190
228
|
finalize,
|
191
229
|
cast,
|
192
|
-
|
230
|
+
mutable,
|
193
231
|
as,
|
194
|
-
|
232
|
+
default,
|
233
|
+
optional
|
195
234
|
)
|
196
|
-
SmartCore::Initializer::Attribute::Factory.create(
|
197
|
-
name, type, type_system, privacy, finalize, cast,
|
235
|
+
SmartCore::Initializer::Attribute::Factory::Option.create(
|
236
|
+
name, type, type_system, privacy, finalize, cast, mutable, as, default, optional
|
198
237
|
)
|
199
238
|
end
|
200
239
|
|
@@ -207,27 +246,77 @@ class SmartCore::Initializer::Constructor::Definer
|
|
207
246
|
SmartCore::Initializer::Extensions::ExtInit.new(block)
|
208
247
|
end
|
209
248
|
|
210
|
-
# @param parameter [SmartCore::Initializer::Attribute]
|
249
|
+
# @param parameter [SmartCore::Initializer::Attribute::Value::Param]
|
211
250
|
# @return [void]
|
212
251
|
#
|
213
252
|
# @api private
|
214
253
|
# @since 0.1.0
|
254
|
+
# @version 0.8.0
|
255
|
+
# rubocop:disable Metrics/AbcSize
|
215
256
|
def add_parameter(parameter)
|
216
257
|
klass.__params__ << parameter
|
217
|
-
klass.
|
218
|
-
klass.
|
258
|
+
klass.__send__(:attr_reader, parameter.name)
|
259
|
+
klass.__send__(parameter.privacy, parameter.name)
|
260
|
+
|
261
|
+
if parameter.mutable?
|
262
|
+
# NOTE:
|
263
|
+
# code evaluation approach is used instead of `define_method` approach in order
|
264
|
+
# to avoid the `clojure`-context binding inside the new method (this context can
|
265
|
+
# access the current context or the current variable set and the way to avoid this by
|
266
|
+
# ruby method is more diffcult to support and read insead of the real `code` evaluation)
|
267
|
+
klass.class_eval(<<~METHOD_CODE, __FILE__, __LINE__ + 1)
|
268
|
+
#{parameter.privacy} def #{parameter.name}=(new_value)
|
269
|
+
self.class.__params__[:#{parameter.name}].validate!(new_value)
|
270
|
+
@#{parameter.name} = new_value
|
271
|
+
end
|
272
|
+
METHOD_CODE
|
273
|
+
end
|
274
|
+
|
275
|
+
if parameter.as
|
276
|
+
klass.__send__(:alias_method, parameter.as, parameter.name)
|
277
|
+
klass.__send__(:alias_method, "#{parameter.as}=", "#{parameter.name}=") if parameter.mutable?
|
278
|
+
|
279
|
+
klass.__send__(parameter.privacy, parameter.as)
|
280
|
+
klass.__send__(parameter.privacy, "#{parameter.as}=") if parameter.mutable?
|
281
|
+
end
|
219
282
|
end
|
283
|
+
# rubocop:enable Metrics/AbcSize
|
220
284
|
|
221
|
-
# @param option [SmartCore::Initializer::Attribute]
|
285
|
+
# @param option [SmartCore::Initializer::Attribute::Value::Option]
|
222
286
|
# @return [void]
|
223
287
|
#
|
224
288
|
# @api private
|
225
289
|
# @since 0.1.0
|
290
|
+
# @version 0.8.0
|
291
|
+
# rubocop:disable Metrics/AbcSize
|
226
292
|
def add_option(option)
|
227
293
|
klass.__options__ << option
|
228
|
-
klass.
|
229
|
-
klass.
|
294
|
+
klass.__send__(:attr_reader, option.name)
|
295
|
+
klass.__send__(option.privacy, option.name)
|
296
|
+
|
297
|
+
if option.mutable?
|
298
|
+
# NOTE:
|
299
|
+
# code evaluation approach is used instead of `define_method` approach in order
|
300
|
+
# to avoid the `clojure`-context binding inside the new method (this context can
|
301
|
+
# access the current context or the current variable set and the way to avoid this by
|
302
|
+
# ruby method is more diffcult to support and read insead of the real `code` evaluation)
|
303
|
+
klass.class_eval(<<~METHOD_CODE, __FILE__, __LINE__ + 1)
|
304
|
+
#{option.privacy} def #{option.name}=(new_value)
|
305
|
+
self.class.__options__[:#{option.name}].validate!(new_value)
|
306
|
+
@#{option.name} = new_value
|
307
|
+
end
|
308
|
+
METHOD_CODE
|
309
|
+
end
|
310
|
+
|
311
|
+
if option.as
|
312
|
+
klass.__send__(:alias_method, option.as, option.name)
|
313
|
+
klass.__send__(:alias_method, "#{option.as}=", "#{option.name}=") if option.mutable?
|
314
|
+
|
315
|
+
klass.__send__(option.privacy, option.as)
|
316
|
+
klass.__send__(option.privacy, "#{option.as}=") if option.mutable?
|
317
|
+
end
|
230
318
|
end
|
319
|
+
# rubocop:enable Metrics/AbcSize
|
231
320
|
|
232
321
|
# @param extension [SmartCore::Initializer::Extensions::ExtInit]
|
233
322
|
# @return [void]
|
@@ -72,7 +72,7 @@ class SmartCore::Initializer::Constructor
|
|
72
72
|
#
|
73
73
|
# @api private
|
74
74
|
# @since 0.1.0
|
75
|
-
# @version 0.
|
75
|
+
# @version 0.8.0
|
76
76
|
# rubocop:disable Metrics/AbcSize
|
77
77
|
def prevent_attribute_insufficiency
|
78
78
|
required_parameter_count = klass.__params__.size
|
@@ -83,8 +83,8 @@ class SmartCore::Initializer::Constructor
|
|
83
83
|
"(given #{parameters.size}, expected #{required_parameter_count})"
|
84
84
|
) unless parameters.size == required_parameter_count
|
85
85
|
|
86
|
-
required_options = klass.__options__.reject(&:has_default?).map(&:name)
|
87
|
-
missing_options = required_options.reject { |
|
86
|
+
required_options = klass.__options__.reject(&:has_default?).reject(&:optional?).map(&:name)
|
87
|
+
missing_options = required_options.reject { |option_name| options.key?(option_name) }
|
88
88
|
|
89
89
|
raise(
|
90
90
|
SmartCore::Initializer::OptionArgumentError,
|
@@ -97,7 +97,7 @@ class SmartCore::Initializer::Constructor
|
|
97
97
|
raise(
|
98
98
|
SmartCore::Initializer::OptionArgumentError,
|
99
99
|
"Unknown options: #{unknown_options.join(', ')}"
|
100
|
-
) if unknown_options.any?
|
100
|
+
) if klass.__initializer_settings__.strict_options && unknown_options.any?
|
101
101
|
end
|
102
102
|
# rubocop:enable Metrics/AbcSize
|
103
103
|
|
@@ -124,8 +124,9 @@ class SmartCore::Initializer::Constructor
|
|
124
124
|
end
|
125
125
|
|
126
126
|
attribute.validate!(parameter_value)
|
127
|
-
|
128
127
|
final_value = attribute.finalizer.call(parameter_value, instance)
|
128
|
+
attribute.validate!(final_value)
|
129
|
+
|
129
130
|
instance.instance_variable_set("@#{attribute.name}", final_value)
|
130
131
|
end
|
131
132
|
end
|
@@ -135,21 +136,34 @@ class SmartCore::Initializer::Constructor
|
|
135
136
|
#
|
136
137
|
# @api private
|
137
138
|
# @since 0.1.0
|
138
|
-
# @version 0.
|
139
|
+
# @version 0.8.0
|
140
|
+
# rubocop:disable Metrics/AbcSize
|
139
141
|
def initialize_options(instance)
|
140
142
|
klass.__options__.each do |attribute|
|
141
|
-
option_value = options.fetch(attribute.name)
|
142
|
-
|
143
|
-
|
144
|
-
option_value = attribute.type.cast(option_value)
|
143
|
+
option_value = options.fetch(attribute.name) do
|
144
|
+
# NOTE: `nil` case is a case when an option is `optional`
|
145
|
+
attribute.has_default? ? attribute.default : nil
|
145
146
|
end
|
146
147
|
|
147
|
-
|
148
|
+
# NOTE: (if-block: what if `if` receives `false`?):
|
149
|
+
# For other case passed `attribute` is optional and
|
150
|
+
# should not be type-checked/type-casted/etc.
|
151
|
+
# But optional attributes with defined `default` setting should be
|
152
|
+
# type-checked and type-casted.
|
153
|
+
if options.key?(attribute.name) || attribute.has_default?
|
154
|
+
if !attribute.type.valid?(option_value) && attribute.cast?
|
155
|
+
option_value = attribute.type.cast(option_value)
|
156
|
+
end
|
157
|
+
|
158
|
+
attribute.validate!(option_value)
|
159
|
+
option_value = attribute.finalizer.call(option_value, instance)
|
160
|
+
attribute.validate!(option_value)
|
161
|
+
end
|
148
162
|
|
149
|
-
|
150
|
-
instance.instance_variable_set("@#{attribute.name}", final_value)
|
163
|
+
instance.instance_variable_set("@#{attribute.name}", option_value)
|
151
164
|
end
|
152
165
|
end
|
166
|
+
# rubocop:enable Metrics/AbcSize
|
153
167
|
|
154
168
|
# @param instance [Any]
|
155
169
|
# @return [void]
|
@@ -157,7 +171,7 @@ class SmartCore::Initializer::Constructor
|
|
157
171
|
# @api private
|
158
172
|
# @since 0.1.0
|
159
173
|
def process_original_initializer(instance)
|
160
|
-
instance.
|
174
|
+
instance.__send__(:initialize, *arguments, &block)
|
161
175
|
end
|
162
176
|
|
163
177
|
# @param instance [Any]
|
@@ -108,37 +108,42 @@ module SmartCore::Initializer::DSL
|
|
108
108
|
# @option cast [Boolean]
|
109
109
|
# @option privacy [String, Symbol]
|
110
110
|
# @option finalize [String, Symbol, Proc]
|
111
|
-
# @option
|
111
|
+
# @option mutable [Boolean]
|
112
112
|
# @option as [NilClass, String, Symbol]
|
113
|
-
# @param dynamic_options [Hash<Symbol,Any>]
|
114
113
|
# @return [void]
|
115
114
|
#
|
116
115
|
# @api public
|
117
116
|
# @since 0.1.0
|
118
|
-
# @version 0.
|
117
|
+
# @version 0.8.0
|
119
118
|
def param(
|
120
119
|
name,
|
121
120
|
type = __initializer_settings__.generic_type_object,
|
122
|
-
privacy: SmartCore::Initializer::Attribute::
|
123
|
-
finalize: SmartCore::Initializer::Attribute::
|
124
|
-
cast:
|
121
|
+
privacy: SmartCore::Initializer::Attribute::Value::Param::DEFAULT_PRIVACY_MODE,
|
122
|
+
finalize: SmartCore::Initializer::Attribute::Value::Param::DEFAULT_FINALIZER,
|
123
|
+
cast: __initializer_settings__.auto_cast,
|
125
124
|
type_system: __initializer_settings__.type_system,
|
126
|
-
|
127
|
-
as: SmartCore::Initializer::Attribute::
|
128
|
-
**dynamic_options
|
125
|
+
mutable: SmartCore::Initializer::Attribute::Value::Param::DEFAULT_MUTABLE,
|
126
|
+
as: SmartCore::Initializer::Attribute::Value::Param::DEFAULT_AS
|
129
127
|
)
|
130
128
|
__definer__.define_parameter(
|
131
|
-
name, type, type_system, privacy, finalize, cast,
|
129
|
+
name, type, type_system, privacy, finalize, cast, mutable, as
|
132
130
|
)
|
133
131
|
end
|
134
132
|
|
135
133
|
# @param names [Array<String, Symbol>]
|
134
|
+
# @option mutable [Boolean]
|
135
|
+
# @option privacy [String, Symbol]
|
136
136
|
# @return [void]
|
137
137
|
#
|
138
138
|
# @api public
|
139
139
|
# @since 0.1.0
|
140
|
-
|
141
|
-
|
140
|
+
# @verison 0.8.0
|
141
|
+
def params(
|
142
|
+
*names,
|
143
|
+
mutable: SmartCore::Initializer::Attribute::Value::Param::DEFAULT_MUTABLE,
|
144
|
+
privacy: SmartCore::Initializer::Attribute::Value::Param::DEFAULT_PRIVACY_MODE
|
145
|
+
)
|
146
|
+
__definer__.define_parameters(*names, mutable: mutable, privacy: privacy)
|
142
147
|
end
|
143
148
|
|
144
149
|
# @param name [String, Symbol]
|
@@ -147,37 +152,46 @@ module SmartCore::Initializer::DSL
|
|
147
152
|
# @option privacy [String, Symbol]
|
148
153
|
# @option finalize [String, Symbol, Proc]
|
149
154
|
# @option type_system [String, Symbol]
|
150
|
-
# @option
|
155
|
+
# @option mutable [Boolean]
|
151
156
|
# @option as [NilClass, String, Symbol]
|
152
|
-
# @
|
157
|
+
# @option default [Proc, Any]
|
158
|
+
# @option optional [Boolean]
|
153
159
|
# @return [void]
|
154
160
|
#
|
155
161
|
# @api public
|
156
162
|
# @since 0.1.0
|
157
|
-
# @version 0.
|
163
|
+
# @version 0.8.0
|
158
164
|
def option(
|
159
165
|
name,
|
160
166
|
type = __initializer_settings__.generic_type_object,
|
161
|
-
privacy: SmartCore::Initializer::Attribute::
|
162
|
-
finalize: SmartCore::Initializer::Attribute::
|
163
|
-
cast:
|
167
|
+
privacy: SmartCore::Initializer::Attribute::Value::Option::DEFAULT_PRIVACY_MODE,
|
168
|
+
finalize: SmartCore::Initializer::Attribute::Value::Option::DEFAULT_FINALIZER,
|
169
|
+
cast: __initializer_settings__.auto_cast,
|
164
170
|
type_system: __initializer_settings__.type_system,
|
165
|
-
|
166
|
-
as: SmartCore::Initializer::Attribute::
|
167
|
-
|
171
|
+
mutable: SmartCore::Initializer::Attribute::Value::Option::DEFAULT_MUTABLE,
|
172
|
+
as: SmartCore::Initializer::Attribute::Value::Option::DEFAULT_AS,
|
173
|
+
default: SmartCore::Initializer::Attribute::Value::Option::UNDEFINED_DEFAULT,
|
174
|
+
optional: SmartCore::Initializer::Attribute::Value::Option::DEFAULT_OPTIONAL
|
168
175
|
)
|
169
176
|
__definer__.define_option(
|
170
|
-
name, type, type_system, privacy, finalize, cast,
|
177
|
+
name, type, type_system, privacy, finalize, cast, mutable, as, default, optional
|
171
178
|
)
|
172
179
|
end
|
173
180
|
|
174
181
|
# @param names [Array<String, Symbol>]
|
182
|
+
# @option mutable [Boolean]
|
183
|
+
# @option privacy [String, Symbol]
|
175
184
|
# @return [void]
|
176
185
|
#
|
177
186
|
# @api public
|
178
187
|
# @since 0.1.0
|
179
|
-
|
180
|
-
|
188
|
+
# @version 0.8.0
|
189
|
+
def options(
|
190
|
+
*names,
|
191
|
+
mutable: SmartCore::Initializer::Attribute::Value::Option::DEFAULT_MUTABLE,
|
192
|
+
privacy: SmartCore::Initializer::Attribute::Value::Option::DEFAULT_PRIVACY_MODE
|
193
|
+
)
|
194
|
+
__definer__.define_options(*names, mutable: mutable, privacy: privacy)
|
181
195
|
end
|
182
196
|
|
183
197
|
# @param block [Block]
|