smart_initializer 0.7.0 → 0.8.0
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 +35 -3
- data/Gemfile.lock +38 -38
- data/README.md +260 -46
- data/bin/console +2 -2
- data/gemfiles/with_external_deps.gemfile.lock +38 -38
- data/lib/smart_core/initializer/attribute/factory/base.rb +145 -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 +30 -12
- 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
@@ -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,38 @@ 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
|
-
attribute.
|
148
|
+
if options.key?(attribute.name) || attribute.has_default?
|
149
|
+
if !attribute.type.valid?(option_value) && attribute.cast?
|
150
|
+
option_value = attribute.type.cast(option_value)
|
151
|
+
end
|
152
|
+
|
153
|
+
attribute.validate!(option_value)
|
154
|
+
end
|
155
|
+
# NOTE: (if-block: what if `if` receives `false`?):
|
156
|
+
# For other case passed `attribute` is optional and
|
157
|
+
# should not be type-checked/type-casted/etc.
|
158
|
+
# But optional attributes with defined `default` setting should be
|
159
|
+
# type-checked and type-casted.
|
160
|
+
#
|
161
|
+
# TODO: it should be covered by tests
|
148
162
|
|
149
163
|
final_value = attribute.finalizer.call(option_value, instance)
|
164
|
+
# NOTE: validae `final_value` if only the `option` is provided (passed to constructor)
|
165
|
+
attribute.validate!(final_value) if options.key?(attribute.name)
|
166
|
+
|
150
167
|
instance.instance_variable_set("@#{attribute.name}", final_value)
|
151
168
|
end
|
152
169
|
end
|
170
|
+
# rubocop:enable Metrics/AbcSize
|
153
171
|
|
154
172
|
# @param instance [Any]
|
155
173
|
# @return [void]
|
@@ -157,7 +175,7 @@ class SmartCore::Initializer::Constructor
|
|
157
175
|
# @api private
|
158
176
|
# @since 0.1.0
|
159
177
|
def process_original_initializer(instance)
|
160
|
-
instance.
|
178
|
+
instance.__send__(:initialize, *arguments, &block)
|
161
179
|
end
|
162
180
|
|
163
181
|
# @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]
|
@@ -9,6 +9,14 @@ module SmartCore::Initializer
|
|
9
9
|
# @since 0.1.0
|
10
10
|
ArgumentError = Class.new(SmartCore::ArgumentError)
|
11
11
|
|
12
|
+
# @api public
|
13
|
+
# @since 0.8.0
|
14
|
+
AttributeError = Class.new(Error)
|
15
|
+
|
16
|
+
# @api public
|
17
|
+
# @since 0.8.0
|
18
|
+
UndefinedAttributeError = Class.new(AttributeError)
|
19
|
+
|
12
20
|
# @api public
|
13
21
|
# @since 0.1.0
|
14
22
|
ParameterArgumentError = Class.new(ArgumentError)
|
@@ -17,6 +25,14 @@ module SmartCore::Initializer
|
|
17
25
|
# @since 0.1.0
|
18
26
|
OptionArgumentError = Class.new(ArgumentError)
|
19
27
|
|
28
|
+
# @api public
|
29
|
+
# @since 0.8.0
|
30
|
+
AliasArgumentError = Class.new(ArgumentError)
|
31
|
+
|
32
|
+
# @api public
|
33
|
+
# @since 0.8.0
|
34
|
+
SettingArgumentError = Class.new(ArgumentError)
|
35
|
+
|
20
36
|
# @api public
|
21
37
|
# @since 0.1.0
|
22
38
|
NoDefaultValueError = Class.new(Error)
|
@@ -53,6 +69,10 @@ module SmartCore::Initializer
|
|
53
69
|
# @since 0.1.0
|
54
70
|
TypeSystemError = Class.new(Error)
|
55
71
|
|
72
|
+
# @api public
|
73
|
+
# @since 0.5.1
|
74
|
+
IncorrectTypeError = Class.new(TypeSystemError)
|
75
|
+
|
56
76
|
# @api public
|
57
77
|
# @since 0.1.0
|
58
78
|
TypeAliasNotFoundError = Class.new(TypeSystemError)
|
@@ -73,10 +93,6 @@ module SmartCore::Initializer
|
|
73
93
|
# @since 0.1.0
|
74
94
|
UnsupportedTypeOperationError = Class.new(TypeSystemError)
|
75
95
|
|
76
|
-
# @api public
|
77
|
-
# @since 0.5.1
|
78
|
-
IncorrectTypeError = Class.new(TypeSystemError)
|
79
|
-
|
80
96
|
# @api public
|
81
97
|
# @since 0.1.0
|
82
98
|
TypeCastingUnsupportedError = Class.new(UnsupportedTypeOperationError)
|
@@ -3,23 +3,22 @@
|
|
3
3
|
# @api private
|
4
4
|
# @since 0.3.0
|
5
5
|
module SmartCore::Initializer::Functionality
|
6
|
-
# @return [NilClass]
|
7
|
-
#
|
8
|
-
# @api private
|
9
|
-
# @since 0.3.0
|
10
|
-
INITIAL_TYPE_SYSTEM = nil
|
11
|
-
|
12
6
|
class << self
|
13
|
-
# @option type_system [String, Symbol
|
7
|
+
# @option type_system [String, Symbol]
|
8
|
+
# @option strict_option [Boolean]
|
9
|
+
# @option auto_cast [Boolean]
|
14
10
|
# @return [Module]
|
15
11
|
#
|
16
12
|
# @api private
|
17
13
|
# @since 0.3.0
|
18
|
-
|
14
|
+
# @version 0.8.0
|
15
|
+
def includable_module(type_system:, strict_options:, auto_cast:)
|
19
16
|
Module.new.tap do |extension|
|
20
17
|
extension.singleton_class.define_method(:included) do |base_klass|
|
21
18
|
base_klass.include(::SmartCore::Initializer)
|
22
19
|
base_klass.__initializer_settings__.type_system = type_system
|
20
|
+
base_klass.__initializer_settings__.strict_options = strict_options
|
21
|
+
base_klass.__initializer_settings__.auto_cast = auto_cast
|
23
22
|
end
|
24
23
|
end
|
25
24
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.8.0
|
5
|
+
class SmartCore::Initializer::Settings::AutoCast < SmartCore::Initializer::Settings::Base
|
6
|
+
# @return [void]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.8.0
|
10
|
+
def initialize
|
11
|
+
@value = nil
|
12
|
+
@lock = SmartCore::Engine::Lock.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [Boolean]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
# @since 0.8.0
|
19
|
+
def resolve
|
20
|
+
thread_safe do
|
21
|
+
@value == nil ? SmartCore::Initializer::Configuration[:auto_cast] : @value
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param value [Boolean]
|
26
|
+
# @return [void]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 0.8.0
|
30
|
+
def assign(value)
|
31
|
+
thread_safe do
|
32
|
+
raise(
|
33
|
+
SmartCore::Initializer::SettingArgumentError,
|
34
|
+
":auto_cast setting should be a type of boolean (got: `#{value.class}`)"
|
35
|
+
) unless value.is_a?(::TrueClass) || value.is_a?(::FalseClass)
|
36
|
+
|
37
|
+
@value = value
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.8.0
|
5
|
+
class SmartCore::Initializer::Settings::Base
|
6
|
+
# @return [void]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.8.0
|
10
|
+
def initialize
|
11
|
+
@value = nil
|
12
|
+
@lock = SmartCore::Engine::Lock.new
|
13
|
+
end
|
14
|
+
|
15
|
+
# @!method resolve
|
16
|
+
# @return [Any]
|
17
|
+
# @api private
|
18
|
+
# @since 0.8.0
|
19
|
+
|
20
|
+
# @!method assign(value)
|
21
|
+
# @param value [Any]
|
22
|
+
# @return [void]
|
23
|
+
# @raise [SmartCore::Initializer::SettingArgumentError]
|
24
|
+
# @api private
|
25
|
+
# @since 0.8.0
|
26
|
+
|
27
|
+
# @return [SmartCore::Initializer::Settings::Base]
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
# @since 0.8.0
|
31
|
+
def dup
|
32
|
+
thread_safe do
|
33
|
+
self.class.new.tap do |duplicate|
|
34
|
+
duplicate.instance_variable_set(:@value, @value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @param block [Block]
|
42
|
+
# @return [Any]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
# @since 0.8.0
|
46
|
+
def thread_safe(&block)
|
47
|
+
@lock.synchronize(&block)
|
48
|
+
end
|
49
|
+
end
|