smart_container 0.2.0 → 0.7.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 +2 -2
- data/.travis.yml +7 -13
- data/CHANGELOG.md +30 -15
- data/Gemfile.lock +46 -31
- data/README.md +185 -6
- data/Rakefile +2 -1
- data/lib/smart_core/container.rb +84 -2
- data/lib/smart_core/container/definition_dsl.rb +6 -2
- data/lib/smart_core/container/definition_dsl/commands/definition/register.rb +1 -1
- data/lib/smart_core/container/dependency_resolver.rb +79 -8
- data/lib/smart_core/container/dependency_resolver/route.rb +5 -8
- data/lib/smart_core/container/errors.rb +2 -1
- data/lib/smart_core/container/registry.rb +98 -5
- data/lib/smart_core/container/version.rb +2 -2
- data/smart_container.gemspec +5 -5
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e536932a27a4bcf2ded83ea750978459e8dbf6a34ea35dfac8ef7008db3240d
|
4
|
+
data.tar.gz: 2566b21ef936d31bab5ff8eb6d6d51cd6510db97acf62d9dc55992915094a962
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1c443404d20ac8c6f61ea8bf6d37db0acd4e1131626ca00c75bf26f695262f275ee6814aab3ecd4b0a4c17b4d3f50ae449abb6932e658f0cc325e3e87cba8ea
|
7
|
+
data.tar.gz: 587dac41ae390e811802ca6c5a6a4610d81d4b7cecd1d5de224a409b1724edf180c98d78acc1a81cd9bc06010343d5a42f769acd219d12d395bef06c4f9420c6
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -1,28 +1,22 @@
|
|
1
1
|
---
|
2
2
|
language: ruby
|
3
3
|
cache: bundler
|
4
|
+
os: linux
|
5
|
+
dist: xenial
|
4
6
|
before_install:
|
5
|
-
- gem install bundler
|
7
|
+
- gem install bundler
|
6
8
|
script:
|
7
9
|
- bundle exec rake rubocop
|
8
10
|
- bundle exec rake rspec
|
9
11
|
jobs:
|
10
12
|
fast_finish: true
|
11
13
|
include:
|
12
|
-
- rvm: 2.4.
|
13
|
-
|
14
|
-
- rvm: 2.
|
15
|
-
|
16
|
-
- rvm: 2.6.5
|
17
|
-
os: [linux, osx]
|
18
|
-
- rvm: 2.7.0
|
19
|
-
os: [linux, osx]
|
14
|
+
- rvm: 2.4.10
|
15
|
+
- rvm: 2.5.8
|
16
|
+
- rvm: 2.6.6
|
17
|
+
- rvm: 2.7.1
|
20
18
|
- rvm: ruby-head
|
21
|
-
os: [linux, osx]
|
22
19
|
- rvm: jruby-head
|
23
|
-
os: [linux, osx]
|
24
20
|
allow_failures:
|
25
21
|
- rvm: ruby-head
|
26
|
-
os: [linux, osx]
|
27
22
|
- rvm: jruby-head
|
28
|
-
os: [linux, osx]
|
data/CHANGELOG.md
CHANGED
@@ -1,25 +1,40 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
## [0.
|
4
|
+
## [0.7.0] - 2020-06-20
|
5
|
+
### Added
|
6
|
+
- `SmartCore::Container.define {}` - an ability to avoid explicit class definition that allows
|
7
|
+
to create container instances from an anonymous container class imidietly
|
8
|
+
|
9
|
+
## [0.6.0] - 2020-01-12
|
10
|
+
### Added
|
11
|
+
- Missing memoization flag `:memoize` for runtime-based dependency registration:
|
12
|
+
- `memoize: false` by default;
|
13
|
+
- signature: `SmartCore::Container#register(dependency_name, memoize: false, &dependency)`
|
14
|
+
|
15
|
+
## [0.5.0] - 2020-01-07
|
16
|
+
### Added
|
17
|
+
- Key predicates (`#key?(key)`, `#dependency?(path, memoized: nil/true/false)`, `#namespace?(path)`);
|
18
|
+
|
19
|
+
## [0.4.0] - 2020-01-06
|
20
|
+
### Added
|
21
|
+
- `#keys(all_variants: false)` - return a list of dependency keys
|
22
|
+
(`all_variants: true` is mean "including namespace kaeys");
|
23
|
+
- `#each_dependency(yield_all: false) { |key, value| }` - iterate over conteiner's dependencies
|
24
|
+
(`yield_all: true` will include nested containers to iteration process);
|
25
|
+
### Fixed
|
26
|
+
- `SmartCore::Container::ResolvingError` class has incorrect message attribute name;
|
27
|
+
|
28
|
+
## [0.3.0] - 2020-01-05
|
29
|
+
### Changed
|
30
|
+
- Dependency resolving is not memoized by default (previously: totally memoized 😱);
|
31
|
+
|
32
|
+
## [0.2.0] - 2020-01-05
|
5
33
|
### Changed
|
6
34
|
- (Private API (`SmartCore::Container::RegistryBuilder`)) improved semantics:
|
7
35
|
- `build_state` is renamed to `initialise`;
|
8
36
|
- `build_definitions` is renamed to `define`;
|
9
|
-
- (Public API) Support for memoized dependencies (all dependencies are memoized by default)
|
10
|
-
```ruby
|
11
|
-
class MyContainer < SmartCore::Container
|
12
|
-
namespace(:some_naespace) do
|
13
|
-
# memoized by default
|
14
|
-
register(:random_number) { rand(1000) }
|
15
|
-
# explicit memoization
|
16
|
-
register(:random_number, memoized: true) { rand(1000) }
|
17
|
-
|
18
|
-
# register non-memoizable dependency
|
19
|
-
register(:random_number, memoized: false) { rand(1000) }
|
20
|
-
end
|
21
|
-
end
|
22
|
-
```
|
37
|
+
- (Public API) Support for memoized dependencies (all dependencies are memoized by default);
|
23
38
|
|
24
39
|
## [0.1.0] - 2020-01-02
|
25
40
|
|
data/Gemfile.lock
CHANGED
@@ -1,83 +1,98 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
smart_container (0.
|
5
|
-
smart_engine (~> 0.
|
4
|
+
smart_container (0.6.0)
|
5
|
+
smart_engine (~> 0.5)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
11
|
-
|
10
|
+
activesupport (6.0.2.2)
|
11
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
12
|
+
i18n (>= 0.7, < 2)
|
13
|
+
minitest (~> 5.1)
|
14
|
+
tzinfo (~> 1.1)
|
15
|
+
zeitwerk (~> 2.2)
|
16
|
+
armitage-rubocop (0.81.0)
|
17
|
+
rubocop (= 0.81.0)
|
12
18
|
rubocop-performance (= 1.5.2)
|
13
|
-
rubocop-rails (= 2.
|
14
|
-
rubocop-rake (= 0.5.
|
15
|
-
rubocop-rspec (= 1.
|
19
|
+
rubocop-rails (= 2.5.2)
|
20
|
+
rubocop-rake (= 0.5.1)
|
21
|
+
rubocop-rspec (= 1.38.1)
|
16
22
|
ast (2.4.0)
|
17
23
|
coderay (1.1.2)
|
24
|
+
concurrent-ruby (1.1.6)
|
18
25
|
diff-lcs (1.3)
|
19
26
|
docile (1.3.2)
|
27
|
+
i18n (1.8.2)
|
28
|
+
concurrent-ruby (~> 1.0)
|
20
29
|
jaro_winkler (1.5.4)
|
21
|
-
|
22
|
-
|
30
|
+
method_source (1.0.0)
|
31
|
+
minitest (5.14.0)
|
23
32
|
parallel (1.19.1)
|
24
|
-
parser (2.7.0
|
33
|
+
parser (2.7.1.0)
|
25
34
|
ast (~> 2.4.0)
|
26
|
-
pry (0.
|
27
|
-
coderay (~> 1.1
|
28
|
-
method_source (~>
|
29
|
-
rack (2.
|
35
|
+
pry (0.13.1)
|
36
|
+
coderay (~> 1.1)
|
37
|
+
method_source (~> 1.0)
|
38
|
+
rack (2.2.2)
|
30
39
|
rainbow (3.0.0)
|
31
40
|
rake (13.0.1)
|
41
|
+
rexml (3.2.4)
|
32
42
|
rspec (3.9.0)
|
33
43
|
rspec-core (~> 3.9.0)
|
34
44
|
rspec-expectations (~> 3.9.0)
|
35
45
|
rspec-mocks (~> 3.9.0)
|
36
46
|
rspec-core (3.9.1)
|
37
47
|
rspec-support (~> 3.9.1)
|
38
|
-
rspec-expectations (3.9.
|
48
|
+
rspec-expectations (3.9.1)
|
39
49
|
diff-lcs (>= 1.2.0, < 2.0)
|
40
50
|
rspec-support (~> 3.9.0)
|
41
51
|
rspec-mocks (3.9.1)
|
42
52
|
diff-lcs (>= 1.2.0, < 2.0)
|
43
53
|
rspec-support (~> 3.9.0)
|
44
54
|
rspec-support (3.9.2)
|
45
|
-
rubocop (0.
|
55
|
+
rubocop (0.81.0)
|
46
56
|
jaro_winkler (~> 1.5.1)
|
47
57
|
parallel (~> 1.10)
|
48
|
-
parser (>= 2.
|
58
|
+
parser (>= 2.7.0.1)
|
49
59
|
rainbow (>= 2.2.2, < 4.0)
|
60
|
+
rexml
|
50
61
|
ruby-progressbar (~> 1.7)
|
51
|
-
unicode-display_width (>= 1.4.0, <
|
62
|
+
unicode-display_width (>= 1.4.0, < 2.0)
|
52
63
|
rubocop-performance (1.5.2)
|
53
64
|
rubocop (>= 0.71.0)
|
54
|
-
rubocop-rails (2.
|
65
|
+
rubocop-rails (2.5.2)
|
66
|
+
activesupport
|
55
67
|
rack (>= 1.1)
|
56
68
|
rubocop (>= 0.72.0)
|
57
|
-
rubocop-rake (0.5.
|
69
|
+
rubocop-rake (0.5.1)
|
58
70
|
rubocop
|
59
|
-
rubocop-rspec (1.
|
71
|
+
rubocop-rspec (1.38.1)
|
60
72
|
rubocop (>= 0.68.1)
|
61
73
|
ruby-progressbar (1.10.1)
|
62
|
-
simplecov (0.
|
74
|
+
simplecov (0.18.5)
|
63
75
|
docile (~> 1.1)
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
76
|
+
simplecov-html (~> 0.11)
|
77
|
+
simplecov-html (0.12.2)
|
78
|
+
smart_engine (0.5.0)
|
79
|
+
thread_safe (0.3.6)
|
80
|
+
tzinfo (1.2.7)
|
81
|
+
thread_safe (~> 0.1)
|
82
|
+
unicode-display_width (1.7.0)
|
83
|
+
zeitwerk (2.3.0)
|
69
84
|
|
70
85
|
PLATFORMS
|
71
86
|
ruby
|
72
87
|
|
73
88
|
DEPENDENCIES
|
74
|
-
armitage-rubocop (~> 0.
|
89
|
+
armitage-rubocop (~> 0.81)
|
75
90
|
bundler (~> 2.1)
|
76
|
-
pry (~> 0.
|
91
|
+
pry (~> 0.13)
|
77
92
|
rake (~> 13.0)
|
78
93
|
rspec (~> 3.9)
|
79
|
-
simplecov (~> 0.
|
94
|
+
simplecov (~> 0.18)
|
80
95
|
smart_container!
|
81
96
|
|
82
97
|
BUNDLED WITH
|
83
|
-
2.1.
|
98
|
+
2.1.4
|
data/README.md
CHANGED
@@ -24,35 +24,214 @@ require 'smart_core/container'
|
|
24
24
|
|
25
25
|
## Synopsis (demo)
|
26
26
|
|
27
|
+
- container class creation:
|
28
|
+
|
27
29
|
```ruby
|
28
30
|
class Container < SmartCore::Container
|
29
31
|
namespace(:database) do # support for namespaces
|
30
|
-
register(:resolver) { SomeDatabaseResolver.new } # dependency registration
|
32
|
+
register(:resolver, memoize: true) { SomeDatabaseResolver.new } # dependency registration
|
31
33
|
|
32
34
|
namespace(:cache) do # support for nested naespaces
|
33
|
-
register(:memcached) { MemcachedClient.new }
|
34
|
-
register(:redis) { RedisClient.new }
|
35
|
+
register(:memcached, memoize: true) { MemcachedClient.new }
|
36
|
+
register(:redis, memoize: true) { RedisClient.new }
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
40
|
# root dependencies
|
39
|
-
register(:logger) { Logger.new(STDOUT) }
|
41
|
+
register(:logger, memoize: true) { Logger.new(STDOUT) }
|
40
42
|
|
41
|
-
#
|
42
|
-
register(:random
|
43
|
+
# dependencies are not memoized by default (memoize: false)
|
44
|
+
register(:random) { rand(1000) }
|
43
45
|
end
|
46
|
+
```
|
47
|
+
|
48
|
+
- mixin:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
# full documentaiton is coming;
|
52
|
+
|
53
|
+
class Application
|
54
|
+
include SmartCore::Container::Mixin
|
44
55
|
|
56
|
+
dependencies do
|
57
|
+
namespace(:database) do
|
58
|
+
register(:cache) { MemcachedClient.new }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# access:
|
64
|
+
Application.container
|
65
|
+
Application.new.container # NOTE: the same instance as Application.container
|
66
|
+
```
|
67
|
+
|
68
|
+
- container instantiation and dependency resolving:
|
69
|
+
|
70
|
+
```ruby
|
45
71
|
container = Container.new # create container instance
|
72
|
+
```
|
46
73
|
|
74
|
+
```ruby
|
47
75
|
container['database.resolver'] # => #<SomeDatabaseResolver:0x00007f0f0f1d6332>
|
48
76
|
container['database.cache.redis'] # => #<RedisClient:0x00007f0f0f1d0158>
|
49
77
|
container['logger'] # => #<Logger:0x00007f5f0f2f0158>
|
50
78
|
|
79
|
+
container.resolve('logger') # #resolve(path) is an alias for #[](path)
|
80
|
+
|
51
81
|
# non-memoized dependency
|
52
82
|
container['random'] # => 352
|
53
83
|
container['random'] # => 57
|
84
|
+
|
85
|
+
# trying to resolve a namespace as dependency
|
86
|
+
container['database'] # => SmartCore::Container::ResolvingError
|
87
|
+
|
88
|
+
# but you can fetch any depenendency type (internal containers and values) via #fetch
|
89
|
+
container.fetch('database') # => SmartCore::Container (nested container)
|
90
|
+
container.fetch('database.resolver') # => #<SomeDatabaseResolver:0x00007f0f0f1d6332>
|
91
|
+
```
|
92
|
+
|
93
|
+
- runtime-level dependency/namespace registration:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
container.namespace(:api) do
|
97
|
+
register(:provider) { GoogleProvider } # without memoization
|
98
|
+
end
|
99
|
+
|
100
|
+
container.register('game_api', memoize: true) { 'overwatch' } # with memoization
|
101
|
+
|
102
|
+
container['api.provider'] # => GoogleProvider
|
103
|
+
container['game_api'] # => 'overwatch'
|
104
|
+
```
|
105
|
+
|
106
|
+
- container keys (dependency names):
|
107
|
+
|
108
|
+
```ruby
|
109
|
+
# get dependnecy keys (only dependencies)
|
110
|
+
container.keys
|
111
|
+
# => result:
|
112
|
+
[
|
113
|
+
'database.resolver',
|
114
|
+
'database.cache.memcached',
|
115
|
+
'database.cache.redis',
|
116
|
+
'logger',
|
117
|
+
'random'
|
118
|
+
]
|
119
|
+
```
|
120
|
+
```ruby
|
121
|
+
# get all keys (namespaces and dependencies)
|
122
|
+
container.keys(all_variants: true)
|
123
|
+
# => result:
|
124
|
+
[
|
125
|
+
'database', # namespace
|
126
|
+
'database.resolver',
|
127
|
+
'database.cache', # namespace
|
128
|
+
'database.cache.memcached',
|
129
|
+
'database.cache.redis',
|
130
|
+
'logger',
|
131
|
+
'random'
|
132
|
+
]
|
54
133
|
```
|
55
134
|
|
135
|
+
- key predicates:
|
136
|
+
- `key?(key)` - has dependency or namespace?
|
137
|
+
- `namespace?(path)` - has namespace?
|
138
|
+
- `dependency?(path)` - has dependency?
|
139
|
+
- `dependency?(path, memoized: true)` - has memoized dependency?
|
140
|
+
- `dependency?(path, memoized: false)` - has non-memoized dependency?
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
container.key?('database') # => true
|
144
|
+
container.key?('database.cache.memcached') # => true
|
145
|
+
|
146
|
+
container.dependency?('database') # => false
|
147
|
+
container.dependency?('database.resolver') # => true
|
148
|
+
|
149
|
+
container.namespace?('database') # => true
|
150
|
+
container.namespace?('database.resolver') # => false
|
151
|
+
|
152
|
+
container.dependency?('database.resolver', memoized: true) # => true
|
153
|
+
container.dependency?('database.resolver', memoized: false) # => false
|
154
|
+
|
155
|
+
container.dependency?('random', memoized: true) # => false
|
156
|
+
container.dependency?('random', memoized: false) # => true
|
157
|
+
```
|
158
|
+
|
159
|
+
- state freeze (`#freeze!`, `.#frozen?`):
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
# documentation is coming;
|
163
|
+
```
|
164
|
+
|
165
|
+
- reloading (`#reload!):
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
# documentation is coming;
|
169
|
+
```
|
170
|
+
|
171
|
+
- hash tree (`#hash_tree`, `#hash_tree(resolve_dependencies: true)`):
|
172
|
+
|
173
|
+
```ruby
|
174
|
+
# documentation is coming`;
|
175
|
+
```
|
176
|
+
|
177
|
+
- `SmartCore::Container.define` - avoid explicit class definition (allows to create container instance from an anonymous container class immidietly):
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
# - create from empty container class -
|
181
|
+
|
182
|
+
AppContainer = SmartCore::Container.define do
|
183
|
+
namespace :database do
|
184
|
+
register(:logger) { Logger.new }
|
185
|
+
end
|
186
|
+
end # => an instance of Class<SmartCore::Container>
|
187
|
+
|
188
|
+
AppContainer.resolve('database.logger') # => #<Logger:0x00007f5f0f2f0158>
|
189
|
+
AppContainer['database.logger'] # => #<Logger:0x00007f5f0f2f0158>
|
190
|
+
```
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
# - create from another container class with a custom sub-definitions -
|
194
|
+
|
195
|
+
class BasicContainer < SmartCore::Container
|
196
|
+
namespace(:api) do
|
197
|
+
register(:client) { Kickbox.new }
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
AppContainer = BasicContainer.define do
|
202
|
+
register(:db_driver) { Sequel }
|
203
|
+
end
|
204
|
+
# --- or ---
|
205
|
+
AppContainer = SmartCore::Container.define(BasicContainer) do
|
206
|
+
register(:db_driver) { Sequel }
|
207
|
+
end
|
208
|
+
|
209
|
+
AppContainer['api.client'] # => #<Kickbox:0x00007f5f0f2f0158> (BasicContainer dependency)
|
210
|
+
AppContainer['db_driver'] # => Sequel (AppContainer dependency)
|
211
|
+
```
|
212
|
+
|
213
|
+
---
|
214
|
+
|
215
|
+
## Roadmap
|
216
|
+
|
217
|
+
- support for instant dependency registration:
|
218
|
+
|
219
|
+
```ruby
|
220
|
+
# common (dynamic) way:
|
221
|
+
register('dependency_name') { dependency_value }
|
222
|
+
|
223
|
+
# instant way:
|
224
|
+
register('dependency_name', dependency_value)
|
225
|
+
```
|
226
|
+
|
227
|
+
- support for memoization ignorance during dependency resolving:
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
resolve('logger', :allocate) # Draft
|
231
|
+
```
|
232
|
+
|
233
|
+
- container composition;
|
234
|
+
|
56
235
|
---
|
57
236
|
|
58
237
|
## Contributing
|
data/Rakefile
CHANGED
@@ -4,6 +4,7 @@ require 'bundler/gem_tasks'
|
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
require 'rubocop'
|
6
6
|
require 'rubocop/rake_task'
|
7
|
+
require 'rubocop-rails'
|
7
8
|
require 'rubocop-performance'
|
8
9
|
require 'rubocop-rspec'
|
9
10
|
require 'rubocop-rake'
|
@@ -11,8 +12,8 @@ require 'rubocop-rake'
|
|
11
12
|
RuboCop::RakeTask.new(:rubocop) do |t|
|
12
13
|
config_path = File.expand_path(File.join('.rubocop.yml'), __dir__)
|
13
14
|
t.options = ['--config', config_path]
|
14
|
-
t.requires << 'rubocop-performance'
|
15
15
|
t.requires << 'rubocop-rspec'
|
16
|
+
t.requires << 'rubocop-performance'
|
16
17
|
t.requires << 'rubocop-rake'
|
17
18
|
end
|
18
19
|
|
data/lib/smart_core/container.rb
CHANGED
@@ -20,6 +20,27 @@ module SmartCore
|
|
20
20
|
require_relative 'container/dependency_resolver'
|
21
21
|
require_relative 'container/mixin'
|
22
22
|
|
23
|
+
class << self
|
24
|
+
# @param initial_container_klass [Class<SmartCore::Container>]
|
25
|
+
# @param container_definitions [Block]
|
26
|
+
# @return [SmartCore::Container]
|
27
|
+
#
|
28
|
+
# @api public
|
29
|
+
# @since 0.7.0
|
30
|
+
def define(initial_container_klass = self, &container_definitions)
|
31
|
+
unless initial_container_klass <= SmartCore::Container
|
32
|
+
raise(SmartCore::Container::ArgumentError, <<~ERROR_MESSAGE)
|
33
|
+
Base class should be a type of SmartCore::Container
|
34
|
+
ERROR_MESSAGE
|
35
|
+
end
|
36
|
+
|
37
|
+
Class.new(initial_container_klass, &container_definitions).new
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# @since 0.4.0
|
42
|
+
include ::Enumerable
|
43
|
+
|
23
44
|
# @since 0.1.0
|
24
45
|
include DefinitionDSL
|
25
46
|
|
@@ -44,8 +65,14 @@ module SmartCore
|
|
44
65
|
#
|
45
66
|
# @api public
|
46
67
|
# @sicne 0.1.0
|
47
|
-
def register(
|
48
|
-
|
68
|
+
def register(
|
69
|
+
dependency_name,
|
70
|
+
memoize: SmartCore::Container::Registry::DEFAULT_MEMOIZATION_BEHAVIOR,
|
71
|
+
&dependency_definition
|
72
|
+
)
|
73
|
+
thread_safe do
|
74
|
+
registry.register_dependency(dependency_name, memoize: memoize, &dependency_definition)
|
75
|
+
end
|
49
76
|
end
|
50
77
|
|
51
78
|
# @param namespace_name [String, Symbol]
|
@@ -102,6 +129,61 @@ module SmartCore
|
|
102
129
|
thread_safe { build_registry! }
|
103
130
|
end
|
104
131
|
|
132
|
+
# @option all_variants [Boolean]
|
133
|
+
# @return [Array<String>]
|
134
|
+
#
|
135
|
+
# @api public
|
136
|
+
# @since 0.4.0
|
137
|
+
def keys(all_variants: SmartCore::Container::Registry::DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
|
138
|
+
thread_safe { registry.keys(all_variants: all_variants) }
|
139
|
+
end
|
140
|
+
|
141
|
+
# @param key [String, Symbol]
|
142
|
+
# @return [Boolean]
|
143
|
+
#
|
144
|
+
# @api public
|
145
|
+
# @since 0.5.0
|
146
|
+
def key?(key)
|
147
|
+
thread_safe { DependencyResolver.key?(self, key) }
|
148
|
+
end
|
149
|
+
|
150
|
+
# @param namespace_path [String, Symbol]
|
151
|
+
# @return [Boolean]
|
152
|
+
#
|
153
|
+
# @api public
|
154
|
+
# @since 0.5.0
|
155
|
+
def namespace?(namespace_path)
|
156
|
+
thread_safe { DependencyResolver.namespace?(self, namespace_path) }
|
157
|
+
end
|
158
|
+
|
159
|
+
# @param dependency_path [String, Symbol]
|
160
|
+
# @option memoized [NilClass, Boolean]
|
161
|
+
# @return [Boolean]
|
162
|
+
#
|
163
|
+
# @api public
|
164
|
+
# @since 0.5.0
|
165
|
+
def dependency?(dependency_path, memoized: nil)
|
166
|
+
thread_safe { DependencyResolver.dependency?(self, dependency_path, memoized: memoized) }
|
167
|
+
end
|
168
|
+
|
169
|
+
# @option yield_all [Boolean]
|
170
|
+
# @param block [Block]
|
171
|
+
# @yield [dependency_name, dependency_value]
|
172
|
+
# @yield_param dependency_name [String]
|
173
|
+
# @yield_param dependency_value [Any, SmartCore::Container]
|
174
|
+
# @return [Enumerable]
|
175
|
+
#
|
176
|
+
# @api public
|
177
|
+
# @since 0.4.0
|
178
|
+
def each_dependency(
|
179
|
+
yield_all: SmartCore::Container::Registry::DEFAULT_ITERATION_YIELD_BEHAVIOUR,
|
180
|
+
&block
|
181
|
+
)
|
182
|
+
thread_safe { registry.each_dependency(yield_all: yield_all, &block) }
|
183
|
+
end
|
184
|
+
alias_method :each, :each_dependency
|
185
|
+
alias_method :each_pair, :each_dependency
|
186
|
+
|
105
187
|
# @option resolve_dependencies [Boolean]
|
106
188
|
# @return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]
|
107
189
|
#
|
@@ -69,8 +69,12 @@ class SmartCore::Container
|
|
69
69
|
#
|
70
70
|
# @api public
|
71
71
|
# @since 0.1.0
|
72
|
-
# @version 0.
|
73
|
-
def register(
|
72
|
+
# @version 0.3.0
|
73
|
+
def register(
|
74
|
+
dependency_name,
|
75
|
+
memoize: SmartCore::Container::Registry::DEFAULT_MEMOIZATION_BEHAVIOR,
|
76
|
+
&dependency_definition
|
77
|
+
)
|
74
78
|
@__container_definition_lock__.thread_safe do
|
75
79
|
DependencyCompatability::Definition.prevent_namespace_overlap!(self, dependency_name)
|
76
80
|
|
@@ -36,7 +36,7 @@ module SmartCore::Container::DefinitionDSL::Commands::Definition
|
|
36
36
|
# @since 0.1.0
|
37
37
|
# @version 0.2.0
|
38
38
|
def call(registry)
|
39
|
-
registry.register_dependency(dependency_name, memoize, &dependency_definition)
|
39
|
+
registry.register_dependency(dependency_name, memoize: memoize, &dependency_definition)
|
40
40
|
end
|
41
41
|
|
42
42
|
# @return [SmartCore::Container::DefinitionDSL::Commands::Definition::Register]
|
@@ -5,6 +5,12 @@
|
|
5
5
|
module SmartCore::Container::DependencyResolver
|
6
6
|
require_relative 'dependency_resolver/route'
|
7
7
|
|
8
|
+
# @return [String]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.4.0
|
12
|
+
PATH_PART_SEPARATOR = '.'
|
13
|
+
|
8
14
|
class << self
|
9
15
|
# @param container [SmartCore::Container]
|
10
16
|
# @param dependency_path [String, Symbol]
|
@@ -20,6 +26,54 @@ module SmartCore::Container::DependencyResolver
|
|
20
26
|
container.registry.resolve(dependency_path).reveal
|
21
27
|
end
|
22
28
|
|
29
|
+
# @param container [SmartCore::Container]
|
30
|
+
# @param key [String, Symbol]
|
31
|
+
# @return [Boolean]
|
32
|
+
#
|
33
|
+
# @api private
|
34
|
+
# @since 0.5.0
|
35
|
+
def key?(container, key)
|
36
|
+
extract(container, key)
|
37
|
+
true
|
38
|
+
rescue SmartCore::Container::ResolvingError
|
39
|
+
false
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param container [SmartCore::Container]
|
43
|
+
# @param namespace_path [String, Symbol]
|
44
|
+
# @return [Boolean]
|
45
|
+
#
|
46
|
+
# @api private
|
47
|
+
# @since 0.5.0
|
48
|
+
def namespace?(container, namespace_path)
|
49
|
+
extract(container, namespace_path).is_a?(SmartCore::Container::Entities::Namespace)
|
50
|
+
rescue SmartCore::Container::ResolvingError
|
51
|
+
false
|
52
|
+
end
|
53
|
+
|
54
|
+
# @param container [SmartCore::Container]
|
55
|
+
# @param dependency_path [String, Symbol]
|
56
|
+
# @option memoized [NilClass, Boolean]
|
57
|
+
# @return [Boolean]
|
58
|
+
#
|
59
|
+
# @api private
|
60
|
+
# @since 0.5.0
|
61
|
+
def dependency?(container, dependency_path, memoized: nil)
|
62
|
+
entity = extract(container, dependency_path)
|
63
|
+
|
64
|
+
case
|
65
|
+
when memoized.nil?
|
66
|
+
entity.is_a?(SmartCore::Container::Entities::Dependency)
|
67
|
+
when !!memoized == true
|
68
|
+
entity.is_a?(SmartCore::Container::Entities::MemoizedDependency)
|
69
|
+
when !!memoized == false
|
70
|
+
entity.is_a?(SmartCore::Container::Entities::Dependency) &&
|
71
|
+
!entity.is_a?(SmartCore::Container::Entities::MemoizedDependency)
|
72
|
+
end
|
73
|
+
rescue SmartCore::Container::ResolvingError
|
74
|
+
false
|
75
|
+
end
|
76
|
+
|
23
77
|
# @param container [SmartCore::Container]
|
24
78
|
# @param dependency_path [String, Symbol]
|
25
79
|
# @return [SmartCore::Container, Any]
|
@@ -32,12 +86,11 @@ module SmartCore::Container::DependencyResolver
|
|
32
86
|
#
|
33
87
|
# @api private
|
34
88
|
# @since 0.1.0
|
35
|
-
# @version 0.1.0
|
36
89
|
def resolve(container, dependency_path)
|
37
90
|
entity = container
|
38
91
|
Route.build(dependency_path).each do |cursor|
|
39
92
|
entity = entity.registry.resolve(cursor.current_path)
|
40
|
-
|
93
|
+
prevent_ambiguous_resolving!(cursor, entity)
|
41
94
|
entity = entity.reveal
|
42
95
|
end
|
43
96
|
entity
|
@@ -47,6 +100,25 @@ module SmartCore::Container::DependencyResolver
|
|
47
100
|
|
48
101
|
private
|
49
102
|
|
103
|
+
# @param container [SmartCore::Container]
|
104
|
+
# @param entity_path [String, Symbol]
|
105
|
+
# @return [SmartCore::Container::Entities::Base]
|
106
|
+
#
|
107
|
+
# @api private
|
108
|
+
# @since 0.5.0
|
109
|
+
def extract(container, entity_path)
|
110
|
+
resolved_entity = container
|
111
|
+
extracted_entity = container
|
112
|
+
|
113
|
+
Route.build(entity_path).each do |cursor|
|
114
|
+
resolved_entity = resolved_entity.registry.resolve(cursor.current_path)
|
115
|
+
extracted_entity = resolved_entity
|
116
|
+
resolved_entity = resolved_entity.reveal
|
117
|
+
end
|
118
|
+
|
119
|
+
extracted_entity
|
120
|
+
end
|
121
|
+
|
50
122
|
# @param cursor [SmartCore::Container::DependencyResolver::Route::Cursor]
|
51
123
|
# @param entity [SmartCore::Container::Entities::Base]
|
52
124
|
# @return [void]
|
@@ -54,8 +126,8 @@ module SmartCore::Container::DependencyResolver
|
|
54
126
|
# @raise [SmartCore::Container::ResolvingError]
|
55
127
|
#
|
56
128
|
# @api private
|
57
|
-
# @since 0.
|
58
|
-
def
|
129
|
+
# @since 0.5.0
|
130
|
+
def prevent_ambiguous_resolving!(cursor, entity)
|
59
131
|
if cursor.last? && entity.is_a?(SmartCore::Container::Entities::Namespace)
|
60
132
|
raise(
|
61
133
|
SmartCore::Container::ResolvingError.new(
|
@@ -84,10 +156,9 @@ module SmartCore::Container::DependencyResolver
|
|
84
156
|
# @api private
|
85
157
|
# @since 0.1.0
|
86
158
|
def process_resolving_error(dependency_path, error)
|
87
|
-
full_dependency_path = Route.build_path(
|
88
|
-
|
89
|
-
|
90
|
-
MESSAGE
|
159
|
+
full_dependency_path = Route.build_path(error.path_part)
|
160
|
+
message = "#{error.message} (incorrect path: \"#{full_dependency_path}\")"
|
161
|
+
raise(SmartCore::Container::ResolvingError.new(message, path_part: full_dependency_path))
|
91
162
|
end
|
92
163
|
end
|
93
164
|
end
|
@@ -2,18 +2,13 @@
|
|
2
2
|
|
3
3
|
# @api private
|
4
4
|
# @since 0.1.0
|
5
|
+
# @version 0.4.0
|
5
6
|
class SmartCore::Container::DependencyResolver::Route
|
6
7
|
require_relative 'route/cursor'
|
7
8
|
|
8
9
|
# @since 0.1.0
|
9
10
|
include Enumerable
|
10
11
|
|
11
|
-
# @return [String]
|
12
|
-
#
|
13
|
-
# @api private
|
14
|
-
# @since 0.1.0
|
15
|
-
PATH_PART_SEPARATOR = '.'
|
16
|
-
|
17
12
|
class << self
|
18
13
|
# @param path [String, Symbol]
|
19
14
|
# @return [SmartCore::Container::DependencyResolver::Route]
|
@@ -28,8 +23,9 @@ class SmartCore::Container::DependencyResolver::Route
|
|
28
23
|
#
|
29
24
|
# @api private
|
30
25
|
# @since 0.1.0
|
26
|
+
# @version 0.4.0
|
31
27
|
def build_path(*path_parts)
|
32
|
-
path_parts.join(PATH_PART_SEPARATOR)
|
28
|
+
path_parts.join(SmartCore::Container::DependencyResolver::PATH_PART_SEPARATOR)
|
33
29
|
end
|
34
30
|
end
|
35
31
|
|
@@ -50,9 +46,10 @@ class SmartCore::Container::DependencyResolver::Route
|
|
50
46
|
#
|
51
47
|
# @api private
|
52
48
|
# @since 0.1.0
|
49
|
+
# @version 0.4.0
|
53
50
|
def initialize(path)
|
54
51
|
@path = path
|
55
|
-
@path_parts = path.split(PATH_PART_SEPARATOR).freeze
|
52
|
+
@path_parts = path.split(SmartCore::Container::DependencyResolver::PATH_PART_SEPARATOR).freeze
|
56
53
|
@size = @path_parts.size
|
57
54
|
end
|
58
55
|
|
@@ -7,6 +7,24 @@ class SmartCore::Container::Registry
|
|
7
7
|
# @since 0.1.0
|
8
8
|
include Enumerable
|
9
9
|
|
10
|
+
# @return [Boolean]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.3.0
|
14
|
+
DEFAULT_MEMOIZATION_BEHAVIOR = false
|
15
|
+
|
16
|
+
# @return [Boolean]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.4.0
|
20
|
+
DEFAULT_ITERATION_YIELD_BEHAVIOUR = false
|
21
|
+
|
22
|
+
# @return [Boolean]
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
# @since 0.4.0
|
26
|
+
DEFAULT_KEY_EXTRACTION_BEHAVIOUR = false
|
27
|
+
|
10
28
|
# @return [Hash<Symbol,SmartCore::Container::Entity>]
|
11
29
|
#
|
12
30
|
# @api private
|
@@ -38,8 +56,8 @@ class SmartCore::Container::Registry
|
|
38
56
|
#
|
39
57
|
# @api private
|
40
58
|
# @since 0.1.0
|
41
|
-
# @version 0.
|
42
|
-
def register_dependency(name, memoize
|
59
|
+
# @version 0.3.0
|
60
|
+
def register_dependency(name, memoize: DEFAULT_MEMOIZATION_BEHAVIOR, &dependency_definition)
|
43
61
|
thread_safe { add_dependency(name, dependency_definition, memoize) }
|
44
62
|
end
|
45
63
|
|
@@ -78,6 +96,30 @@ class SmartCore::Container::Registry
|
|
78
96
|
thread_safe { enumerate(&block) }
|
79
97
|
end
|
80
98
|
|
99
|
+
# @param root_dependency_name [NilClass, String]
|
100
|
+
# @option yield_all [Boolean]
|
101
|
+
# @param block [Block]
|
102
|
+
# @return [Enumerable]
|
103
|
+
#
|
104
|
+
# @api private
|
105
|
+
# @since 0.4.0
|
106
|
+
def each_dependency(
|
107
|
+
root_dependency_name = nil,
|
108
|
+
yield_all: DEFAULT_ITERATION_YIELD_BEHAVIOUR,
|
109
|
+
&block
|
110
|
+
)
|
111
|
+
thread_safe { iterate(root_dependency_name, yield_all: yield_all, &block) }
|
112
|
+
end
|
113
|
+
|
114
|
+
# @option all_variants [Boolean]
|
115
|
+
# @return [Array<String>]
|
116
|
+
#
|
117
|
+
# @api private
|
118
|
+
# @since 0.4.0
|
119
|
+
def keys(all_variants: DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
|
120
|
+
thread_safe { extract_keys(all_variants: all_variants) }
|
121
|
+
end
|
122
|
+
|
81
123
|
# @return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]
|
82
124
|
#
|
83
125
|
# @api private
|
@@ -152,9 +194,8 @@ class SmartCore::Container::Registry
|
|
152
194
|
dependency_name = indifferently_accessable_name(entity_path)
|
153
195
|
registry.fetch(dependency_name)
|
154
196
|
rescue KeyError
|
155
|
-
|
156
|
-
|
157
|
-
MESSAGE
|
197
|
+
error_message = "Entity with \"#{dependency_name}\" name does not exist"
|
198
|
+
raise(SmartCore::Container::ResolvingError.new(error_message, path_part: dependency_name))
|
158
199
|
end
|
159
200
|
|
160
201
|
# @param dependency_name [String, Symbol]
|
@@ -209,6 +250,58 @@ class SmartCore::Container::Registry
|
|
209
250
|
namespace_entity.tap { namespace_entity.append_definitions(dependencies_definition) }
|
210
251
|
end
|
211
252
|
|
253
|
+
# @param root_dependency_name [String, NilClass]
|
254
|
+
# @param block [Block]
|
255
|
+
# @option yield_all [Boolean]
|
256
|
+
# @yield [dependency_name, dependency]
|
257
|
+
# @yield_param dependency_name [String]
|
258
|
+
# @yield_param dependency [Any]
|
259
|
+
# @return [Enumerable]
|
260
|
+
#
|
261
|
+
# @api private
|
262
|
+
# @since 0.4.0
|
263
|
+
def iterate(root_dependency_name = nil, yield_all: DEFAULT_ITERATION_YIELD_BEHAVIOUR, &block)
|
264
|
+
enumerator = Enumerator.new do |yielder|
|
265
|
+
registry.each_pair do |dependency_name, dependency|
|
266
|
+
final_dependency_name =
|
267
|
+
if root_dependency_name
|
268
|
+
"#{root_dependency_name}" \
|
269
|
+
"#{SmartCore::Container::DependencyResolver::PATH_PART_SEPARATOR}" \
|
270
|
+
"#{dependency_name}"
|
271
|
+
else
|
272
|
+
dependency_name
|
273
|
+
end
|
274
|
+
|
275
|
+
case dependency
|
276
|
+
when SmartCore::Container::Entities::Dependency
|
277
|
+
yielder.yield(final_dependency_name, dependency.reveal)
|
278
|
+
when SmartCore::Container::Entities::Namespace
|
279
|
+
yielder.yield(final_dependency_name, dependency.reveal) if yield_all
|
280
|
+
dependency.reveal.registry.each_dependency(
|
281
|
+
final_dependency_name,
|
282
|
+
yield_all: yield_all,
|
283
|
+
&block
|
284
|
+
)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
block_given? ? enumerator.each(&block) : enumerator.each
|
290
|
+
end
|
291
|
+
|
292
|
+
# @option all_variants [Boolean]
|
293
|
+
# @return [Array<String>]
|
294
|
+
#
|
295
|
+
# @api private
|
296
|
+
# @since 0.4.0
|
297
|
+
def extract_keys(all_variants: DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
|
298
|
+
Set.new.tap do |dependency_names|
|
299
|
+
iterate(yield_all: all_variants) do |dependency_name, _dependency|
|
300
|
+
dependency_names << dependency_name
|
301
|
+
end
|
302
|
+
end.to_a
|
303
|
+
end
|
304
|
+
|
212
305
|
# @param name [String, Symbol]
|
213
306
|
# @return [void]
|
214
307
|
#
|
data/smart_container.gemspec
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require_relative 'lib/smart_core/container/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.required_ruby_version = Gem::Requirement.new('>= 2.4.
|
6
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.4.10')
|
7
7
|
|
8
8
|
spec.name = 'smart_container'
|
9
9
|
spec.version = SmartCore::Container::VERSION
|
@@ -27,12 +27,12 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
28
|
spec.require_paths = ['lib']
|
29
29
|
|
30
|
-
spec.add_dependency 'smart_engine', '~> 0.
|
30
|
+
spec.add_dependency 'smart_engine', '~> 0.5'
|
31
31
|
|
32
32
|
spec.add_development_dependency 'bundler', '~> 2.1'
|
33
33
|
spec.add_development_dependency 'rake', '~> 13.0'
|
34
34
|
spec.add_development_dependency 'rspec', '~> 3.9'
|
35
|
-
spec.add_development_dependency 'armitage-rubocop', '~> 0.
|
36
|
-
spec.add_development_dependency 'simplecov', '~> 0.
|
37
|
-
spec.add_development_dependency 'pry', '~> 0.
|
35
|
+
spec.add_development_dependency 'armitage-rubocop', '~> 0.81'
|
36
|
+
spec.add_development_dependency 'simplecov', '~> 0.18'
|
37
|
+
spec.add_development_dependency 'pry', '~> 0.13'
|
38
38
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_container
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rustam Ibragimov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: smart_engine
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.5'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,42 +72,42 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0.
|
75
|
+
version: '0.81'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0.
|
82
|
+
version: '0.81'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: simplecov
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0.
|
89
|
+
version: '0.18'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0.
|
96
|
+
version: '0.18'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: pry
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '0.
|
103
|
+
version: '0.13'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: '0.
|
110
|
+
version: '0.13'
|
111
111
|
description: Thread-safe semanticaly-defined IoC/DI Container
|
112
112
|
email:
|
113
113
|
- iamdaiver@gmail.com
|
@@ -178,7 +178,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
178
178
|
requirements:
|
179
179
|
- - ">="
|
180
180
|
- !ruby/object:Gem::Version
|
181
|
-
version: 2.4.
|
181
|
+
version: 2.4.10
|
182
182
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
183
183
|
requirements:
|
184
184
|
- - ">="
|