smart_container 0.3.0 → 0.4.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 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