containable 2.2.1 → 2.3.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: 014d1582fc52d294c3c860f611866683ec3308dd0f95c23083defc93b8db0f8a
4
- data.tar.gz: 321b1a573df10500ddbc4eede5503537caee0cb3380cfd296eb6baf68c478f4e
3
+ metadata.gz: 7c5be0b5f9d940c754f77ded0f06992cb9d1dc13e45ec055ccde1a877fbe1782
4
+ data.tar.gz: 156d209e8b763fe0f995fa19bb709282537c2122c1a54e05c167e082f052055d
5
5
  SHA512:
6
- metadata.gz: 3dd07f1911ceb4df23b10dcdbf5364c0391a6341e5869a0f1dc94c619b493c1acaec058d315d1bc3b6c2c93dd6a2c5c5c9e23e80366098ee4e5bd99a7263a3dd
7
- data.tar.gz: 7f3d378b0e9a2ecb0385e50ffcd07f9054e559104e5ebd3f2ca3ad17f1c4999107d5748aeb0a316e67742ac594901b649f8a0490cc2726dc913fc37e498a07f2
6
+ metadata.gz: 8c6fa5e47492849f7d67121a0725dae9466f0bb79fdc4e014f8ba80daa02d68507b6efb3dc56a3d75fc87b0130d2b001127a78c709eb8a54b345bd8f09d14d53
7
+ data.tar.gz: 9a43d1dfce8ea6768240a48c4292b10b26abd984fa51c969dd68b6bd4a5170edaabac3a7dc716b9995559b592b844bb3bea4ab0a01b7aa5535a298c67dd2f757
checksums.yaml.gz.sig CHANGED
Binary file
data/README.adoc CHANGED
@@ -110,7 +110,7 @@ module Container
110
110
  end
111
111
  ----
112
112
 
113
- With the above, `1` (literal) will be associated with the `:demo` key. This is perfect for registering literals, constants, or any objects you immediately want evaluated or have a reference to. To lazily register a dependency, use a block with parameters:
113
+ With the above, `1` (literal) will be associated with the `:demo` key. This is perfect for registering literals, constants, or any objects you immediately want evaluated or have a reference to. To lazy register a dependency, use a block with parameters:
114
114
 
115
115
  [source,ruby]
116
116
  ----
@@ -155,7 +155,7 @@ end
155
155
  Use `:cache` and `:fresh` to direct how your closures will be resolved. Here's what each does:
156
156
 
157
157
  * `+:cache+`: Ensures the same object is answered each time the key is resolved. In the above example, this means the `one` dependency will always answer the _same_ instance of an `Object` when resolved. This is default behavior so you don't need to define this key and is only shown for explicit illustration purposes.
158
- * `+:fresh+`: Ensures a new object is answered each time the key is resolved. In the above example, this means that the `two` dependency will always answer a _different_ instance of an `Object`. You want to use this when you want to lazily resolve a dependency while still wanting a new instance each time.
158
+ * `+:fresh+`: Ensures a new object is answered each time the key is resolved. In the above example, this means that the `two` dependency will always answer a _different_ instance of an `Object`. You want to use this when you want to lazy resolve a dependency while still wanting a new instance each time.
159
159
 
160
160
  💡 The `as` key is only applied when using a closure with no parameters and is ignored otherwise. This means you don't need to supply this key when using literals.
161
161
 
@@ -188,8 +188,15 @@ module Container
188
188
  register :one, 1
189
189
  end
190
190
 
191
+ # Single (preferred)
191
192
  Container.register :two, 2
193
+
194
+ # Single (setter)
192
195
  Container[:three] = 3
196
+
197
+ # Multiples.
198
+ Container.register(:four, 4)
199
+ .register(:five, 5)
193
200
  ----
194
201
 
195
202
  With the above, a combination of `.register` and `.[]=` (setter) messages are used. While the latter is handy, the former is preferred for improved readability.
@@ -246,7 +253,7 @@ Container[:two] # #<Proc:0x000000012e9f8718 /demo:23>
246
253
  Container[:three] # #<Proc:0x000000012e9f8628 /demo:24 (lambda)>
247
254
  ----
248
255
 
249
- With the above, you can see `:one` was immediately resolved to the value of `1` even though it was wrapped in a closure to begin with. This happened because the closure had no parameters so was safe to resolve. Again, this allows you to lazily resolve a dependency until you need it.
256
+ With the above, you can see `:one` was immediately resolved to the value of `1` even though it was wrapped in a closure to begin with. This happened because the closure had no parameters so was safe to resolve. Again, this allows you to lazy resolve a dependency until you need it.
250
257
 
251
258
  For keys `:two` and `:three`, we have a closure that has at least one parameter so remains a closure. This allows you to supply required arguments later. Here's a closer look of using the `:two` and `:three` dependencies:
252
259
 
@@ -277,7 +284,65 @@ Container[:two] # #<Object:0x000000012d237728>
277
284
  Container[:two] # #<Object:0x000000012d2de550>
278
285
  ----
279
286
 
280
- Notice `one` always answers the same instance of an `Object` while `two` always answers a new instance of `Object`. By using `:fresh`, this allows you to lazily evaluate your closure while disabling default caching support.
287
+ Notice `one` always answers the same instance of an `Object` while `two` always answers a new instance of `Object`. By using `:fresh`, this allows you to lazy evaluate your closure while disabling default caching support.
288
+
289
+ === Merges
290
+
291
+ You can merge dependencies from another container into your current container. Consider the following containers:
292
+
293
+ [source,ruby]
294
+ ----
295
+ module Primary
296
+ extend Containable
297
+
298
+ register :zero, 0
299
+ end
300
+
301
+ module Secondary
302
+ extend Containable
303
+
304
+ namespace :one do
305
+ register :two, 2
306
+ end
307
+
308
+ register :three, 3
309
+ end
310
+
311
+ module Other
312
+ extend Containable
313
+
314
+ register :four, 4
315
+ end
316
+ ----
317
+
318
+ With the above, this means you can do the following:
319
+
320
+ [source,ruby]
321
+ ----
322
+ # Merge a single dependency.
323
+ Primary.merge Secondary, :three
324
+ Primary[:three] # 3
325
+
326
+ # Merge multiple dependencies.
327
+ Primary.merge Secondary, "one.two", :three
328
+ Primary["one.two"] # 2
329
+ Primary[:three] # 3
330
+
331
+ # Merge with a namespace.
332
+ Primary.merge Secondary, "one.two", :three, namespace: :top
333
+ Primary["top.one.two"] # 2
334
+ Primary["top.three"] # 3
335
+
336
+ # Merge as fresh (normally, the default is cache).
337
+ Primary.merge Secondary, "one.two", as: :fresh
338
+
339
+ # Merge with repeated messages since it answers itself.
340
+ Primary.merge(Secondary, :three)
341
+ .merge(Other, :four)
342
+
343
+ Primary[:three] # 3
344
+ Primary[:four] # 4
345
+ ----
281
346
 
282
347
  === Namespaces
283
348
 
@@ -316,6 +381,16 @@ Container["two.green"] # "green"
316
381
  Container["three.silver"] # "silver"
317
382
  ----
318
383
 
384
+ You can also send multiple messages to create a namespace register a dependency:
385
+
386
+ [source,]
387
+ ----
388
+ Container.namespace(:one)
389
+ .register(:two, 2)
390
+ ----
391
+
392
+ This is a convenience that should only be used in rare situations because defining your namespaces and associated dependencies using block syntax improves readability.
393
+
319
394
  === Enumeration
320
395
 
321
396
  Enumeration is possible but limited. Given the following:
data/containable.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "containable"
5
- spec.version = "2.2.1"
5
+ spec.version = "2.3.0"
6
6
  spec.authors = ["Brooke Kuhlmann"]
7
7
  spec.email = ["brooke@alchemists.io"]
8
8
  spec.homepage = "https://alchemists.io/projects/containable"
@@ -40,11 +40,22 @@ module Containable
40
40
  fail FrozenError, "Can't modify frozen container." if dependencies.frozen?
41
41
 
42
42
  target.call key, value, as:, &block
43
+ self
44
+ end
45
+ end
46
+
47
+ def define_merge target: register
48
+ define_method :merge do |other, *keys, namespace: nil, as: :cache|
49
+ target.merge(other, *keys, namespace:, as:)
50
+ self
43
51
  end
44
52
  end
45
53
 
46
54
  def define_namespace target = register
47
- define_method(:namespace) { |name, &block| target.namespace name, &block }
55
+ define_method :namespace do |name, &block|
56
+ target.namespace name, &block
57
+ self
58
+ end
48
59
  end
49
60
 
50
61
  def define_resolve target = resolver
@@ -25,14 +25,21 @@ module Containable
25
25
  check_duplicate key, namespaced_key
26
26
  check_directive as
27
27
  dependencies[namespaced_key] = [block || value, as]
28
+ self
28
29
  end
29
30
 
30
31
  alias register call
31
32
 
33
+ def merge other, *keys, namespace: nil, as: :cache
34
+ keys.each { call [namespace, it].compact.join("."), other[it], as: }
35
+ self
36
+ end
37
+
32
38
  def namespace(name, &)
33
39
  keys.clear if depth.zero?
34
40
  keys.append name
35
41
  visit(&)
42
+ self
36
43
  end
37
44
 
38
45
  protected
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: containable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brooke Kuhlmann
@@ -90,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
90
  - !ruby/object:Gem::Version
91
91
  version: '0'
92
92
  requirements: []
93
- rubygems_version: 4.0.11
93
+ rubygems_version: 4.0.12
94
94
  specification_version: 4
95
95
  summary: A thread-safe dependency injection container.
96
96
  test_files: []
metadata.gz.sig CHANGED
Binary file