smart_initializer 0.7.0 → 0.8.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 +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
|