smart_container 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 919cbfa847aa6931a64cf70c07269a0883ac0b5f47e9b84243854b0ea626f49e
4
- data.tar.gz: b9fcfbf5060a973bf1aa8e81d8a78cbdabf243e585dea583e64904e698c094dc
3
+ metadata.gz: bb1bc1e5f80263730638b0b0387105364777f87e957b5f673c27c219f206273d
4
+ data.tar.gz: 0d1a505edb3b4456ab44ecfe52071b1cb5555f51680d3a48de68fb12bd11dcad
5
5
  SHA512:
6
- metadata.gz: 282c7f32da7c8029518b72f94b1047ed71046db44b0e18c9eef2557158bbf3ad97bb5ed658af9a836105964175fa2fd5a5b6ddb0568700b39ed471e7b6ec4c28
7
- data.tar.gz: bfabb455faa37954f0700d2f910e6de93ed4194bb9bb63d45918af7e81de92a5f07f3edf503c922a363d682d6a227cad64a5e5f4c53b355db0b8018757397bb4
6
+ metadata.gz: 3959674748c1dcc2564bd6edc9ee0acdc3770b0bd260d50c7a1bba5906fee6725ff577e90a2b36b0a81910c423020431810b2a052f42c65826bfc8dcabe7dc22
7
+ data.tar.gz: f01f97eda299d91b22f730de1eba90e546f9f4de0362218bc0b8f86d8800acd6abf3d2214e223c0246f5c1d4b4742b71c7223ada409a3665765c088c88ab207e
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  language: ruby
3
3
  cache: bundler
4
+ os: linux
4
5
  before_install:
5
6
  - gem install bundler -v 2.1.2
6
7
  script:
@@ -10,19 +11,11 @@ jobs:
10
11
  fast_finish: true
11
12
  include:
12
13
  - rvm: 2.4.9
13
- os: [linux, osx]
14
14
  - rvm: 2.5.7
15
- os: [linux, osx]
16
15
  - rvm: 2.6.5
17
- os: [linux, osx]
18
16
  - rvm: 2.7.0
19
- os: [linux, osx]
20
17
  - rvm: ruby-head
21
- os: [linux, osx]
22
18
  - rvm: jruby-head
23
- os: [linux, osx]
24
19
  allow_failures:
25
20
  - rvm: ruby-head
26
- os: [linux, osx]
27
21
  - rvm: jruby-head
28
- os: [linux, osx]
@@ -1,6 +1,15 @@
1
1
  # Changelog
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.4.0] - 2020-01-06
5
+ ### Added
6
+ - `#keys(all_variants: false)` - return a list of dependency keys
7
+ (`all_variants: true` is mean "including namespace kaeys");
8
+ - `#each_dependency(yield_all: false) { |key, value| }` - iterate over conteiner's dependencies
9
+ (`yield_all: true` will include nested containers to iteration process);
10
+ ### Fixed
11
+ - `SmartCore::Container::ResolvingError` class has incorrect message attribute name;
12
+
4
13
  ## [0.3.0] - 2020-01-05
5
14
  ### Changed
6
15
  - Dependency resolving is not memoized by default (previously: totally memoized 😱);
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- smart_container (0.3.0)
4
+ smart_container (0.4.0)
5
5
  smart_engine (~> 0.2)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -24,6 +24,8 @@ 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
@@ -41,16 +43,60 @@ class Container < SmartCore::Container
41
43
  # dependencies are not memoized by default (memoize: false)
42
44
  register(:random) { rand(1000) }
43
45
  end
46
+ ```
44
47
 
48
+ - container instantiation and dependency resolving:
49
+
50
+ ```ruby
45
51
  container = Container.new # create container instance
52
+ ```
46
53
 
54
+ ```ruby
47
55
  container['database.resolver'] # => #<SomeDatabaseResolver:0x00007f0f0f1d6332>
48
56
  container['database.cache.redis'] # => #<RedisClient:0x00007f0f0f1d0158>
49
57
  container['logger'] # => #<Logger:0x00007f5f0f2f0158>
50
58
 
59
+ container.resolve('logger') # #resolve(path) is an alias for #[](path)
60
+
51
61
  # non-memoized dependency
52
62
  container['random'] # => 352
53
63
  container['random'] # => 57
64
+
65
+ # trying to resolve a namespace as dependency
66
+ container['database'] # => SmartCore::Container::ResolvingError
67
+
68
+ # but you can fetch any depenendency type (internal containers and values) via #fetch
69
+ container.fetch('database') # => SmartCore::Container (nested container)
70
+ container.fetch('database.resolver') # => #<SomeDatabaseResolver:0x00007f0f0f1d6332>
71
+ ```
72
+
73
+ - container keys (dependency names):
74
+
75
+ ```ruby
76
+ # get dependnecy keys (only dependencies)
77
+ container.keys
78
+ # => result:
79
+ [
80
+ 'database.resolver',
81
+ 'database.cache.memcached',
82
+ 'database.cache.redis',
83
+ 'logger',
84
+ 'random'
85
+ ]
86
+ ```
87
+ ```ruby
88
+ # get all keys (namespaces and dependencies)
89
+ container.keys(all_variants: true)
90
+ # => result:
91
+ [
92
+ 'database', # namespace
93
+ 'database.resolver',
94
+ 'database.cache', # namespace
95
+ 'database.cache.memcached',
96
+ 'database.cache.redis',
97
+ 'logger',
98
+ 'random'
99
+ ]
54
100
  ```
55
101
 
56
102
  ---
@@ -20,6 +20,9 @@ module SmartCore
20
20
  require_relative 'container/dependency_resolver'
21
21
  require_relative 'container/mixin'
22
22
 
23
+ # @since 0.4.0
24
+ include ::Enumerable
25
+
23
26
  # @since 0.1.0
24
27
  include DefinitionDSL
25
28
 
@@ -102,6 +105,33 @@ module SmartCore
102
105
  thread_safe { build_registry! }
103
106
  end
104
107
 
108
+ # @option all_variants [Boolean]
109
+ # @return [Array<String>]
110
+ #
111
+ # @api public
112
+ # @since 0.4.0
113
+ def keys(all_variants: SmartCore::Container::Registry::DEFAULT_KEY_EXTRACTION_BEHAVIOUR)
114
+ thread_safe { registry.keys(all_variants: all_variants) }
115
+ end
116
+
117
+ # @option yield_all [Boolean]
118
+ # @param block [Block]
119
+ # @yield [dependency_name, dependency_value]
120
+ # @yield_param dependency_name [String]
121
+ # @yield_param dependency_value [Any, SmartCore::Container]
122
+ # @return [Enumerable]
123
+ #
124
+ # @api public
125
+ # @since 0.4.0
126
+ def each_dependency(
127
+ yield_all: SmartCore::Container::Registry::DEFAULT_ITERATION_YIELD_BEHAVIOUR,
128
+ &block
129
+ )
130
+ thread_safe { registry.each_dependency(yield_all: yield_all, &block) }
131
+ end
132
+ alias_method :each, :each_dependency
133
+ alias_method :each_pair, :each_dependency
134
+
105
135
  # @option resolve_dependencies [Boolean]
106
136
  # @return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]
107
137
  #
@@ -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]
@@ -84,10 +90,9 @@ module SmartCore::Container::DependencyResolver
84
90
  # @api private
85
91
  # @since 0.1.0
86
92
  def process_resolving_error(dependency_path, error)
87
- full_dependency_path = Route.build_path(dependency_path, error.path_part)
88
- raise(SmartCore::Container::ResolvingError.new(<<~MESSAGE, path_part: full_dependency_path))
89
- #{error.message} (incorrect path: "#{full_dependency_path}")
90
- MESSAGE
93
+ full_dependency_path = Route.build_path(error.path_part)
94
+ message = "#{error.message} (incorrect path: \"#{full_dependency_path}\")"
95
+ raise(SmartCore::Container::ResolvingError.new(message, path_part: full_dependency_path))
91
96
  end
92
97
  end
93
98
  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
 
@@ -57,7 +57,8 @@ class SmartCore::Container
57
57
  #
58
58
  # @api private
59
59
  # @since 0.1.0
60
- def initialize(messegae = nil, path_part:)
60
+ # @version 0.4.0
61
+ def initialize(message = nil, path_part:)
61
62
  @path_part = path_part
62
63
  super(message)
63
64
  end
@@ -13,6 +13,18 @@ class SmartCore::Container::Registry
13
13
  # @since 0.3.0
14
14
  DEFAULT_MEMOIZATION_BEHAVIOR = false
15
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
+
16
28
  # @return [Hash<Symbol,SmartCore::Container::Entity>]
17
29
  #
18
30
  # @api private
@@ -84,6 +96,30 @@ class SmartCore::Container::Registry
84
96
  thread_safe { enumerate(&block) }
85
97
  end
86
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
+
87
123
  # @return [Hash<String|Symbol,SmartCore::Container::Entities::Base|Any>]
88
124
  #
89
125
  # @api private
@@ -158,9 +194,8 @@ class SmartCore::Container::Registry
158
194
  dependency_name = indifferently_accessable_name(entity_path)
159
195
  registry.fetch(dependency_name)
160
196
  rescue KeyError
161
- raise(SmartCore::Container::ResolvingError.new(<<~MESSAGE, path_part: dependency_name))
162
- Entity with \"#{dependency_name}\" name does not exist
163
- MESSAGE
197
+ error_message = "Entity with \"#{dependency_name}\" name does not exist"
198
+ raise(SmartCore::Container::ResolvingError.new(error_message, path_part: dependency_name))
164
199
  end
165
200
 
166
201
  # @param dependency_name [String, Symbol]
@@ -215,6 +250,58 @@ class SmartCore::Container::Registry
215
250
  namespace_entity.tap { namespace_entity.append_definitions(dependencies_definition) }
216
251
  end
217
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
+
218
305
  # @param name [String, Symbol]
219
306
  # @return [void]
220
307
  #
@@ -4,7 +4,7 @@ module SmartCore
4
4
  class Container
5
5
  # @api public
6
6
  # @since 0.1.0
7
- # @version 0.3.0
8
- VERSION = '0.3.0'
7
+ # @version 0.4.0
8
+ VERSION = '0.4.0'
9
9
  end
10
10
  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.3.0
4
+ version: 0.4.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-01-05 00:00:00.000000000 Z
11
+ date: 2020-01-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: smart_engine