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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e16ae20c546597ce7c44382a790934260b44b1ebff59a51c7c7eb366205d969f
|
4
|
+
data.tar.gz: 14af5a449ae56ecf8b38d22c3ea0957f4896070556fec3c280a4b265e78f63de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cecc3bc1e93570d2c8cb0cc11c1b409c24d6b401a9a8225de4676a10915c7e08a1bf869315650f9ddf66c7b5dc4602e96d2a0717a83289b6fec79cb795d5dde9
|
7
|
+
data.tar.gz: 6ed53102d9c016fbdad65a3f4ad2b2aec6ad567596ec3e255f33a55f979eab5180138ae496f1ff5eafae3ae71019229ea8840d9fc1608ddcbb821a6f2aeffae5
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,48 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [0.8.0] - 2021-12-04
|
5
|
+
### Added
|
6
|
+
- New options for option and param attributes:
|
7
|
+
- Support for attribute **aliasing** (`:as` parameter);
|
8
|
+
- supports: `option`, `param`;
|
9
|
+
- Support for attribute **auto-casting** (`:auto_cast` parameter);
|
10
|
+
- supports: `option`, `param`;
|
11
|
+
- Support for **mutable** attributes (`:mutable` parameter) with type-validation inside;
|
12
|
+
- supports: `option`, `options`, `param`, `params`;
|
13
|
+
- Support for **optional** attributes (`:optional` parameter);
|
14
|
+
- supports: `option`;
|
15
|
+
- **SmartCore::Initializer::Configuration**:
|
16
|
+
- Configuration setting `strict_options` now works separately "per-class" in all configs manner
|
17
|
+
(each class shares the global state but has own state too)
|
18
|
+
- Support for per-class/global `:auto_cast` configuration;
|
19
|
+
- provides a global/per-class behavior for `:cast` option (`false` by default);
|
20
|
+
- `options` declaration now supports `privacy` option;
|
21
|
+
- `params` declaration now supports `privacy` option;
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
- Drop support of **Ruby@2.4**;
|
25
|
+
- `:default` attribute parameter now duplicates the passed value during object instantiation;
|
26
|
+
- `:default` attribute parameter only works with `option` attribute (`param` can't have `default` parameter now);
|
27
|
+
- Attribute values generated by `:finalize` are type-validated now too;
|
28
|
+
- Now lambda-based `:finalize` attributes are being checked for the signature during attribute declaration;
|
29
|
+
- Some error messages have become more readable;
|
30
|
+
|
31
|
+
## Fixed
|
32
|
+
- `send` method overlaping/rewriting: otions and params named as `send` breaks the internal
|
33
|
+
framework-related invocations of the attribute definitioning inside the custom object constructor
|
34
|
+
(this name rewrites internal Ruby's `send` method and brokes some things);
|
35
|
+
|
4
36
|
## [0.7.0] - 2021-06-23
|
5
|
-
|
37
|
+
### Added
|
6
38
|
- `strict_options` config option for non-strict checking of passed options;
|
7
39
|
|
8
40
|
## [0.6.0] - 2021-06-23
|
9
|
-
|
41
|
+
### Added
|
10
42
|
- Validation messages for incorrect attribute types;
|
11
43
|
|
12
44
|
## [0.5.0] - 2021-01-18
|
13
|
-
|
45
|
+
### Changed
|
14
46
|
- Updated `smart_types` dependency (`~> 0.4.0`) to guarantee **Ruby@3** compatibility;
|
15
47
|
- Updated development dependencies;
|
16
48
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
smart_initializer (0.
|
4
|
+
smart_initializer (0.8.0)
|
5
5
|
qonfig (~> 0.24)
|
6
6
|
smart_engine (~> 0.11)
|
7
7
|
smart_types (~> 0.4)
|
@@ -9,39 +9,39 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
activesupport (6.1.
|
12
|
+
activesupport (6.1.4.1)
|
13
13
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
14
|
i18n (>= 1.6, < 2)
|
15
15
|
minitest (>= 5.1)
|
16
16
|
tzinfo (~> 2.0)
|
17
17
|
zeitwerk (~> 2.3)
|
18
|
-
armitage-rubocop (1.
|
19
|
-
rubocop (= 1.
|
20
|
-
rubocop-performance (= 1.
|
21
|
-
rubocop-rails (= 2.
|
22
|
-
rubocop-rake (= 0.
|
23
|
-
rubocop-rspec (= 2.
|
18
|
+
armitage-rubocop (1.23.0.1)
|
19
|
+
rubocop (= 1.23.0)
|
20
|
+
rubocop-performance (= 1.12.0)
|
21
|
+
rubocop-rails (= 2.12.4)
|
22
|
+
rubocop-rake (= 0.6.0)
|
23
|
+
rubocop-rspec (= 2.6.0)
|
24
24
|
ast (2.4.2)
|
25
25
|
coderay (1.1.3)
|
26
|
-
concurrent-ruby (1.1.
|
26
|
+
concurrent-ruby (1.1.9)
|
27
27
|
diff-lcs (1.4.4)
|
28
|
-
docile (1.
|
29
|
-
i18n (1.8.
|
28
|
+
docile (1.4.0)
|
29
|
+
i18n (1.8.11)
|
30
30
|
concurrent-ruby (~> 1.0)
|
31
31
|
method_source (1.0.0)
|
32
|
-
minitest (5.14.
|
33
|
-
parallel (1.
|
34
|
-
parser (3.0.
|
32
|
+
minitest (5.14.4)
|
33
|
+
parallel (1.21.0)
|
34
|
+
parser (3.0.3.1)
|
35
35
|
ast (~> 2.4.1)
|
36
|
-
pry (0.14.
|
36
|
+
pry (0.14.1)
|
37
37
|
coderay (~> 1.1)
|
38
38
|
method_source (~> 1.0)
|
39
|
-
qonfig (0.
|
39
|
+
qonfig (0.26.0)
|
40
40
|
rack (2.2.3)
|
41
41
|
rainbow (3.0.0)
|
42
|
-
rake (13.0.
|
43
|
-
regexp_parser (2.0
|
44
|
-
rexml (3.2.
|
42
|
+
rake (13.0.6)
|
43
|
+
regexp_parser (2.2.0)
|
44
|
+
rexml (3.2.5)
|
45
45
|
rspec (3.10.0)
|
46
46
|
rspec-core (~> 3.10.0)
|
47
47
|
rspec-expectations (~> 3.10.0)
|
@@ -54,51 +54,51 @@ GEM
|
|
54
54
|
rspec-mocks (3.10.2)
|
55
55
|
diff-lcs (>= 1.2.0, < 2.0)
|
56
56
|
rspec-support (~> 3.10.0)
|
57
|
-
rspec-support (3.10.
|
58
|
-
rubocop (1.
|
57
|
+
rspec-support (3.10.3)
|
58
|
+
rubocop (1.23.0)
|
59
59
|
parallel (~> 1.10)
|
60
60
|
parser (>= 3.0.0.0)
|
61
61
|
rainbow (>= 2.2.2, < 4.0)
|
62
62
|
regexp_parser (>= 1.8, < 3.0)
|
63
63
|
rexml
|
64
|
-
rubocop-ast (>= 1.
|
64
|
+
rubocop-ast (>= 1.12.0, < 2.0)
|
65
65
|
ruby-progressbar (~> 1.7)
|
66
66
|
unicode-display_width (>= 1.4.0, < 3.0)
|
67
|
-
rubocop-ast (1.
|
68
|
-
parser (>=
|
69
|
-
rubocop-performance (1.
|
70
|
-
rubocop (>=
|
67
|
+
rubocop-ast (1.14.0)
|
68
|
+
parser (>= 3.0.1.1)
|
69
|
+
rubocop-performance (1.12.0)
|
70
|
+
rubocop (>= 1.7.0, < 2.0)
|
71
71
|
rubocop-ast (>= 0.4.0)
|
72
|
-
rubocop-rails (2.
|
72
|
+
rubocop-rails (2.12.4)
|
73
73
|
activesupport (>= 4.2.0)
|
74
74
|
rack (>= 1.1)
|
75
|
-
rubocop (>=
|
76
|
-
rubocop-rake (0.
|
77
|
-
rubocop
|
78
|
-
rubocop-rspec (2.1.0)
|
75
|
+
rubocop (>= 1.7.0, < 2.0)
|
76
|
+
rubocop-rake (0.6.0)
|
79
77
|
rubocop (~> 1.0)
|
80
|
-
|
78
|
+
rubocop-rspec (2.6.0)
|
79
|
+
rubocop (~> 1.19)
|
81
80
|
ruby-progressbar (1.11.0)
|
82
81
|
simplecov (0.21.2)
|
83
82
|
docile (~> 1.1)
|
84
83
|
simplecov-html (~> 0.11)
|
85
84
|
simplecov_json_formatter (~> 0.1)
|
86
85
|
simplecov-html (0.12.3)
|
87
|
-
simplecov_json_formatter (0.1.
|
86
|
+
simplecov_json_formatter (0.1.3)
|
88
87
|
smart_engine (0.11.0)
|
89
|
-
smart_types (0.
|
88
|
+
smart_types (0.7.0)
|
90
89
|
smart_engine (~> 0.11)
|
91
90
|
tzinfo (2.0.4)
|
92
91
|
concurrent-ruby (~> 1.0)
|
93
|
-
unicode-display_width (2.
|
94
|
-
zeitwerk (2.
|
92
|
+
unicode-display_width (2.1.0)
|
93
|
+
zeitwerk (2.5.1)
|
95
94
|
|
96
95
|
PLATFORMS
|
97
96
|
x86_64-darwin-19
|
98
97
|
x86_64-darwin-20
|
98
|
+
x86_64-darwin-21
|
99
99
|
|
100
100
|
DEPENDENCIES
|
101
|
-
armitage-rubocop (~> 1.
|
101
|
+
armitage-rubocop (~> 1.23)
|
102
102
|
bundler (~> 2.2)
|
103
103
|
pry (~> 0.14)
|
104
104
|
rake (~> 13.0)
|
@@ -107,4 +107,4 @@ DEPENDENCIES
|
|
107
107
|
smart_initializer!
|
108
108
|
|
109
109
|
BUNDLED WITH
|
110
|
-
2.2.
|
110
|
+
2.2.31
|
data/README.md
CHANGED
@@ -1,8 +1,14 @@
|
|
1
|
-
# SmartCore::Initializer · [](https://badge.fury.io/rb/smart_initializer)
|
1
|
+
# SmartCore::Initializer · <a target="_blank" href="https://github.com/Cado-Labs"><img src="https://github.com/Cado-Labs/cado-labs-logos/raw/main/cado_labs_badge.svg" alt="Supported by Cado Labs" style="max-width: 100%; height: 20px"></a> · [](https://badge.fury.io/rb/smart_initializer)
|
2
2
|
|
3
3
|
A simple and convenient way to declare complex constructors with a support for various commonly used type systems.
|
4
4
|
(**in active development**).
|
5
5
|
|
6
|
+
---
|
7
|
+
|
8
|
+
<img src="https://github.com/Cado-Labs/cado-labs-resources/blob/main/cado_labs_supporting_rounded.svg" alt="Supported by Cado Labs" />
|
9
|
+
|
10
|
+
---
|
11
|
+
|
6
12
|
## Installation
|
7
13
|
|
8
14
|
```ruby
|
@@ -24,9 +30,21 @@ require 'smart_core/initializer'
|
|
24
30
|
## Table of contents
|
25
31
|
|
26
32
|
- [Synopsis](#synopsis)
|
33
|
+
- [Initialization flow](#initialization-flow)
|
34
|
+
- [Attribute value definition flow](#attribute-value-definition-flow-during-object-allocation-and-construction)
|
35
|
+
- [Constructor definition](#constructor-definition)
|
36
|
+
- [param](#param)
|
37
|
+
- [option](#option)
|
38
|
+
- [params](#params)
|
39
|
+
- [options](#options)
|
40
|
+
- [param and params signature](#param-and-params-signature)
|
41
|
+
- [option and options signature](#option-and-options-signature)
|
42
|
+
- [Initializer integration](#initializer-integration)
|
43
|
+
- [Basic Example](#basic-example)
|
27
44
|
- [Access to the instance attributes](#access-to-the-instance-attributes)
|
28
45
|
- [Configuration](#configuration)
|
29
46
|
- [Type aliasing](#type-aliasing)
|
47
|
+
- [Type auto-casting](#type-auto-casting)
|
30
48
|
- [Initialization extension](#initialization-extension)
|
31
49
|
- [Plugins](#plugins)
|
32
50
|
- [thy-types](#plugin-thy-types)
|
@@ -37,51 +55,69 @@ require 'smart_core/initializer'
|
|
37
55
|
|
38
56
|
## Synopsis
|
39
57
|
|
40
|
-
|
58
|
+
#### Initialization flow
|
41
59
|
|
42
|
-
1. Parameter + Option definitioning;
|
43
|
-
2. Original
|
60
|
+
1. Parameter + Option definitioning and initialization;
|
61
|
+
2. Original **#initialize** invokation;
|
44
62
|
3. Initialization extensions invokation;
|
45
63
|
|
46
|
-
**
|
64
|
+
**NOTE!**: original constructor is called after **SmarteCore::Initializer**'s constructor
|
65
|
+
in order to guarantee the validity of the SmartCore::Initializer's functionality
|
66
|
+
(such as `attribute overlap chek`, `instant type checking`, `value post-processing by finalize`, etc)
|
67
|
+
|
68
|
+
#### Attribute value definition flow (during object allocation and construction):
|
69
|
+
|
70
|
+
1. `original value`
|
71
|
+
2. *(if defined)*: `default value` (default value is used when `original value` is not defined)
|
72
|
+
3. *(if defined)*: `finalize`;
|
73
|
+
|
74
|
+
---
|
75
|
+
|
76
|
+
### Constructor definition DSL
|
77
|
+
|
78
|
+
**NOTE**: last `Hash` argument will be treated as `kwarg`s;
|
79
|
+
|
80
|
+
#### param
|
47
81
|
|
48
82
|
- `param` - defines name-like attribute:
|
49
|
-
- `cast` - type-cast received value if value has invalid type;
|
50
|
-
- `privacy` - reader incapsulation level;
|
51
|
-
- `finalize` - value post-processing (receives method name or proc);
|
52
|
-
- `type_system` - differently chosen type system for the current attribute;
|
53
|
-
- (
|
54
|
-
- `
|
55
|
-
-
|
56
|
-
- `privacy` - reader incapsulation level;
|
57
|
-
- `finalize` - value post-processing (receives method name or proc);
|
58
|
-
- `default` - defalut value (if an attribute is not provided);
|
59
|
-
- `type_system` - differently chosen type system for the current attribute;
|
60
|
-
- last `Hash` argument will be treated as `kwarg`s;
|
83
|
+
- `cast` (optional) - type-cast received value if value has invalid type;
|
84
|
+
- `privacy` (optional) - reader incapsulation level;
|
85
|
+
- `finalize` (optional) - value post-processing (receives method name or proc) (the result value type is also validate);
|
86
|
+
- `type_system` (optional) - differently chosen type system for the current attribute;
|
87
|
+
- `as` (optional)- attribute alias (be careful with naming aliases that overlap the names of other attributes);
|
88
|
+
- `mutable` (optional) - generate type-validated attr_writer in addition to attr_reader (`false` by default)
|
89
|
+
- (**limitation**) param has no `:default` option;
|
61
90
|
|
62
|
-
####
|
91
|
+
#### option
|
63
92
|
|
64
|
-
|
65
|
-
|
93
|
+
- `option` - defined kwarg-like attribute:
|
94
|
+
- `cast` (optional) - type-cast received value if value has invalid type;
|
95
|
+
- `privacy` (optional) - reader incapsulation level;
|
96
|
+
- `as` (optional) - attribute alias (be careful with naming aliases that overlap the names of other attributes);
|
97
|
+
- `mutable` (optional) - generate type-validated attr_writer in addition to attr_reader (`false` by default)
|
98
|
+
- `optional` (optional) - mark attribut as optional (you can may not initialize optional attributes,
|
99
|
+
their values will be initialized with `nil` or by `default:` parameter);
|
100
|
+
- `finalize` (optional) - value post-processing (receives method name or proc) (the result value type is also validate);
|
101
|
+
- expects `Proc` object or `symbol`/`string` isntance method;
|
102
|
+
- `default` (optional) - defalut value (if an attribute is not provided);
|
103
|
+
- expects `Proc` object or a simple value of any type;
|
104
|
+
- non-proc values will be `dup`licate during initialization;
|
105
|
+
- `type_system` (optional) - differently chosen type system for the current attribute;
|
66
106
|
|
67
|
-
|
68
|
-
include SmartCore::Initializer
|
69
|
-
end
|
70
|
-
```
|
107
|
+
#### params
|
71
108
|
|
72
|
-
|
73
|
-
|
109
|
+
- `params` - define a series of parameters;
|
110
|
+
- `:mutable` (optional) - (`false` by default);
|
111
|
+
- `:privacy` (optional) - (`:public` by default);
|
74
112
|
|
75
|
-
|
76
|
-
include SmartCore::Initializer(type_system: :smart_types)
|
77
|
-
end
|
113
|
+
#### options
|
78
114
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
```
|
115
|
+
- `options` - define a series of options;
|
116
|
+
- `:mutable` (optional) - (`false` by default);
|
117
|
+
- `:privacy` (optional) - (`:public` by default);
|
83
118
|
|
84
|
-
|
119
|
+
|
120
|
+
#### `param` and `params` signautre:
|
85
121
|
|
86
122
|
```ruby
|
87
123
|
param <attribute_name>,
|
@@ -89,10 +125,19 @@ param <attribute_name>,
|
|
89
125
|
cast: false, # false by default
|
90
126
|
privacy: :public, # :public by default
|
91
127
|
finalize: proc { |value| value }, # no finalization by default
|
128
|
+
finalize: :some_method, # use this apporiach in order to finalize by `some_method(value)` instance method
|
129
|
+
as: :some_alias, # define attribute alias
|
130
|
+
mutable: true, # (false by default) generate type-validated attr_writer in addition to attr_reader
|
92
131
|
type_system: :smart_types # used by default
|
93
132
|
```
|
94
133
|
|
95
|
-
|
134
|
+
```ruby
|
135
|
+
params <atribute_name1>, <attribute_name2>, <attribute_name3>, ...,
|
136
|
+
mutable: true, # generate type-validated attr_writer in addition to attr_reader (false by default);
|
137
|
+
privacy: :private # incapsulate all attributes as private
|
138
|
+
```
|
139
|
+
|
140
|
+
#### `option` and `options` signature:
|
96
141
|
|
97
142
|
```ruby
|
98
143
|
option <attribute_name>,
|
@@ -100,11 +145,58 @@ option <attribute_name>,
|
|
100
145
|
cast: false, # false by default
|
101
146
|
privacy: :public, # :public by default
|
102
147
|
finalize: proc { |value| value }, # no finalization by default
|
148
|
+
finalize: :some_method, # use this apporiach in order to finalize by `some_method(value)` instance method
|
103
149
|
default: 123, # no default value by default
|
150
|
+
default: proc { 123 }, # use proc/lambda object for dynamic initialization
|
151
|
+
as: :some_alias, # define attribute alias
|
152
|
+
mutable: true, # (false by default) generate type-validated attr_writer in addition to attr_reader
|
153
|
+
optional: true # (false by default) mark attribute as optional (attribute will be defined with `nil` or by `default:` value)
|
104
154
|
type_system: :smart_types # used by default
|
105
155
|
```
|
106
156
|
|
107
|
-
|
157
|
+
```ruby
|
158
|
+
options <attribute_name1>, <attribute_name2>, <attribute_name3>, ...,
|
159
|
+
mutable: true, # generate type-validated attr_writer in addition to attr_reader (false by default);
|
160
|
+
privacy: :private # incapsulate all attributes as private
|
161
|
+
```
|
162
|
+
|
163
|
+
---
|
164
|
+
|
165
|
+
## Initializer integration
|
166
|
+
|
167
|
+
- supports per-class configurations;
|
168
|
+
- possible configurations:
|
169
|
+
- `:type_system` - chosen type-system (`smart_types` by default);
|
170
|
+
- `:strict_options` - fail extra kwarg-attributes, passed to the constructor (`true` by default);
|
171
|
+
- `:auto_cast` - type-cast all values to the declared attribute type (`false` by default);
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
# with pre-configured type system (:smart_types, see Configuration doc)
|
175
|
+
|
176
|
+
class MyStructure
|
177
|
+
include SmartCore::Initializer
|
178
|
+
end
|
179
|
+
```
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
# with manually chosen settings
|
183
|
+
|
184
|
+
class MyStructure
|
185
|
+
include SmartCore::Initializer(
|
186
|
+
type_system: :smart_types, # use smart_types
|
187
|
+
auto_cast: true, # type-cast all values by default
|
188
|
+
strict_options: false # ignore extra kwargs passed to the constructor
|
189
|
+
)
|
190
|
+
end
|
191
|
+
|
192
|
+
class AnotherStructure
|
193
|
+
include SmartCore::Initializer(type_system: :thy_types) # use thy_types and global defaults
|
194
|
+
end
|
195
|
+
```
|
196
|
+
|
197
|
+
---
|
198
|
+
|
199
|
+
### Basic Example:
|
108
200
|
|
109
201
|
|
110
202
|
```ruby
|
@@ -114,13 +206,34 @@ class User
|
|
114
206
|
include SmartCore::Initializer(type_system: :smart_types)
|
115
207
|
|
116
208
|
param :user_id, SmartCore::Types::Value::Integer, cast: false, privacy: :public
|
209
|
+
param :login, :string, mutable: true
|
210
|
+
|
117
211
|
option :role, default: :user, finalize: -> { |value| Role.find(name: value) }
|
118
212
|
|
213
|
+
# NOTE: for method-based finalizetion use `your_method(value)` isntance method of your class;
|
214
|
+
# NOTE: for dynamic default values use `proc` objects and `lambda` objects;
|
215
|
+
|
119
216
|
params :name, :password
|
120
217
|
options :metadata, :enabled
|
121
218
|
end
|
122
219
|
|
123
|
-
|
220
|
+
# with correct types (incorrect types will raise SmartCore::Initializer::IncorrectTypeError)
|
221
|
+
object = User.new(1, 'kek123', 'John', 'test123', role: :admin, metadata: {}, enabled: false)
|
222
|
+
|
223
|
+
# attribute accessing:
|
224
|
+
object.user_id # => 1
|
225
|
+
object.login # => 'kek123'
|
226
|
+
object.name # => 'John'
|
227
|
+
object.password # => 'test123'
|
228
|
+
object.role # => :admin
|
229
|
+
object.metadata # => {}
|
230
|
+
object.enabled # => false
|
231
|
+
|
232
|
+
# attribute mutation (only mutable attributes have a mutator):
|
233
|
+
object.login = 123 # => (type vlaidation error) raises SmartCore::Initializer::IncorrectTypeError (expected String, got Integer)
|
234
|
+
object.login # => 'kek123'
|
235
|
+
object.login = 'pek456'
|
236
|
+
object.login # => 'pek456'
|
124
237
|
```
|
125
238
|
|
126
239
|
---
|
@@ -152,27 +265,65 @@ user.__attributes__ # => { first_name: 'Rustam', second_name: 'Ibragimov', age:
|
|
152
265
|
|
153
266
|
## Configuration
|
154
267
|
|
155
|
-
-
|
268
|
+
- **configuration setitngs**:
|
269
|
+
- `:default_type_system` - default type system (`smart_types` by default);
|
270
|
+
- `:strict_options` - fail on extra kwarg-attributes passed to the constructor (`true` by default);
|
271
|
+
- `:auto_cast` - type-cast all values to the declared attribute type (`false` by default);
|
272
|
+
- by default, all classes uses and inherits the Global configuration;
|
156
273
|
- you can read config values via `[]` or `.config.settings` or `.config[key]`;
|
157
|
-
-
|
158
|
-
|
159
|
-
|
274
|
+
- each class can be configured separately (in `include` invocation);
|
275
|
+
- global configuration affects classes used the default global configs in run-time;
|
276
|
+
- each class can be re-configured separately in run-time;
|
277
|
+
- based on `Qonfig` gem;
|
160
278
|
|
161
279
|
```ruby
|
162
|
-
#
|
280
|
+
# Global configuration:
|
281
|
+
|
163
282
|
SmartCore::Initializer::Configuration.configure do |config|
|
164
283
|
config.default_type_system = :smart_types # default setting value
|
165
284
|
config.strict_options = true # default setting value
|
285
|
+
config.auto_cast = false # default setting value
|
166
286
|
end
|
167
287
|
```
|
168
288
|
|
169
289
|
```ruby
|
170
|
-
#
|
290
|
+
# Read configs:
|
291
|
+
|
171
292
|
SmartCore::Initializer::Configuration[:default_type_system]
|
172
293
|
SmartCore::Initializer::Configuration.config[:default_type_system]
|
173
294
|
SmartCore::Initializer::Configuration.config.settings.default_type_system
|
174
295
|
```
|
175
296
|
|
297
|
+
```ruby
|
298
|
+
# per-class configuration:
|
299
|
+
|
300
|
+
class Parameters
|
301
|
+
include SmartCore::Initializer(auto_cast: true, strict_options: false)
|
302
|
+
# 1. use globally configured `smart_types` (default value)
|
303
|
+
# 2. type-cast all attributes by default (auto_cast: true)
|
304
|
+
# 3. ignore extra kwarg-attributes passed to the constructor (strict_options: false)
|
305
|
+
end
|
306
|
+
|
307
|
+
class User
|
308
|
+
include SmartCore::Initializer(type_system: :thy_types)
|
309
|
+
# 1. use :thy_types isntead of pre-configured :smart_types
|
310
|
+
# 2. use pre-configured auto_cast (false by default above)
|
311
|
+
# 3. use pre-configured strict_options ()
|
312
|
+
end
|
313
|
+
```
|
314
|
+
|
315
|
+
```ruby
|
316
|
+
# debug class-related configurations:
|
317
|
+
|
318
|
+
class SomeClass
|
319
|
+
include SmartCore::Initializer(type_system: :thy_types)
|
320
|
+
end
|
321
|
+
|
322
|
+
SomeClass.__initializer_settings__[:type_system] # => :thy_types
|
323
|
+
SomeClass.__initializer_settings__[:auto_cast] # => false
|
324
|
+
SomeClass.__initializer_settings__[:strict_options] # => true
|
325
|
+
```
|
326
|
+
|
176
327
|
---
|
177
328
|
|
178
329
|
## Type aliasing
|
@@ -208,6 +359,63 @@ SmartCore::Initializer::TypeSystem::ThyTypes.type_aliases
|
|
208
359
|
|
209
360
|
---
|
210
361
|
|
362
|
+
## Type-casting
|
363
|
+
|
364
|
+
- make param/option as type-castable:
|
365
|
+
|
366
|
+
```ruby
|
367
|
+
class Order
|
368
|
+
include SmartCore::Initializer
|
369
|
+
|
370
|
+
param :manager, 'string' # cast: false is used by default
|
371
|
+
param :amount, 'float', cast: true
|
372
|
+
|
373
|
+
option :status, :symbol # cast: false is used by default
|
374
|
+
option :is_processed, 'boolean', cast: true
|
375
|
+
option :processed_at, 'time', cast: true
|
376
|
+
end
|
377
|
+
|
378
|
+
order = Order.new(
|
379
|
+
'Daiver',
|
380
|
+
'123.456',
|
381
|
+
status: :pending,
|
382
|
+
is_processed: nil,
|
383
|
+
processed_at: '2021-01-01'
|
384
|
+
)
|
385
|
+
|
386
|
+
order.manager # => 'Daiver'
|
387
|
+
order.amount # => 123.456 (type casted)
|
388
|
+
order.status # => :pending
|
389
|
+
order.is_processed # => false (type casted)
|
390
|
+
order.processed_at # => 2021-01-01 00:00:00 +0300 (type casted)
|
391
|
+
```
|
392
|
+
|
393
|
+
- configure automatic type casting:
|
394
|
+
|
395
|
+
```ruby
|
396
|
+
# per class
|
397
|
+
|
398
|
+
class User
|
399
|
+
include SmartCore::Initializer(auto_cast: true) # auto type cast every attribute
|
400
|
+
|
401
|
+
param :x, 'string'
|
402
|
+
param :y, 'numeric', cast: false # disable type-casting
|
403
|
+
|
404
|
+
option :b, 'integer', cast: false # disable type-casting
|
405
|
+
option :c, 'boolean'
|
406
|
+
end
|
407
|
+
```
|
408
|
+
|
409
|
+
```ruby
|
410
|
+
# globally
|
411
|
+
|
412
|
+
SmartCore::Initializer::Configuration.configure do |config|
|
413
|
+
config.auto_cast = true # false by default
|
414
|
+
end
|
415
|
+
```
|
416
|
+
|
417
|
+
---
|
418
|
+
|
211
419
|
## Initialization extension
|
212
420
|
|
213
421
|
- `ext_init(&block)`:
|
@@ -291,9 +499,9 @@ User.new(123, 'test', { admin: true, age: 22 })
|
|
291
499
|
|
292
500
|
## Roadmap
|
293
501
|
|
294
|
-
- (
|
295
|
-
|
296
|
-
|
502
|
+
- (**thinking** / **discussing**) Finalize should be invoked on `mutable` attributes after mutation too;
|
503
|
+
- Support for `RSpec` doubles and instance_doubles inside the type system integration;
|
504
|
+
- Specs restructuring;
|
297
505
|
- Migrate from `TravisCI` to `GitHub Actions`;
|
298
506
|
- Extract `Type Interop` system to `smart_type-system`;
|
299
507
|
|
@@ -349,6 +557,12 @@ bundle exec rake rubocop -A
|
|
349
557
|
|
350
558
|
Released under MIT License.
|
351
559
|
|
560
|
+
## Supporting
|
561
|
+
|
562
|
+
<a target="_blank" href="https://github.com/Cado-Labs">
|
563
|
+
<img src="https://github.com/Cado-Labs/cado-labs-logos/raw/main/cado_labs_badge.svg" alt="Supported by Cado Labs" style="max-width: 100%;">
|
564
|
+
</a>
|
565
|
+
|
352
566
|
## Authors
|
353
567
|
|
354
568
|
[Rustam Ibragimov](https://github.com/0exp)
|