dry-container 0.4.0 → 0.5.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
  SHA1:
3
- metadata.gz: 674ad0ad74a6d746feaad68d60327231693da1af
4
- data.tar.gz: 7f61c7b298cbccb1f0c0b34d7df4a116d0a500ef
3
+ metadata.gz: 2f11ec3380a6ff086362780a67b687935cff8ddf
4
+ data.tar.gz: 15db84953170fdc3f249d852d01d106f7a904f23
5
5
  SHA512:
6
- metadata.gz: d794c0b798bb18519f10b7625f351193a3e768c7870d57a95adc76cb1d2e4a2c45a679622349c2c3404922346a3108b6c42cafe9a51b7a51dc34790c98ad9f89
7
- data.tar.gz: 5581b7fff68c5eb4e50a8bdd949043b54464f6f103eb6719bc9a6b7ad27a57e077d4b8118d76df8d929bd6d67af2f39fe396505f106263948a74bde96b1bf826
6
+ metadata.gz: f36ffd98d0c80ffd158e1554a09dd89919aeb7c780010a276118ad217db89d9ace865746c18b97321b6022d75dc5a4e46523d27927cd01ee182d0bb3b6b105b8
7
+ data.tar.gz: 7b52ee74e85b40edad15d082ad5fc64a20a00947a8d97d472be013f4f98fe363be5c25f007cd6d089582d0302034b35ed0041ce843e276c896100a9775a2a14a
@@ -0,0 +1,11 @@
1
+ ## v0.5.0
2
+
3
+ ## Added
4
+
5
+ * `memoize` option to `#register` - memoizes items on first resolve ([ivoanjo](https://github.com/ivoanjo))
6
+
7
+ ## Fixed
8
+
9
+ * `required_ruby_version` set to `>= 2.0.0` ([artofhuman](https://github.com/artofhuman))
10
+
11
+ [Compare v0.4.0...HEAD](https://github.com/dry-rb/dry-container/compare/v0.4.0...HEAD)
data/README.md CHANGED
@@ -91,6 +91,29 @@ end
91
91
  container.import(ns)
92
92
  container.resolve('repositories.authentication.users')
93
93
  # => []
94
+
95
+ # You can also register a block that is used to initialize a dependency and
96
+ # then memoize it, allowing several dependencies to be added without
97
+ # enforcing an instantiation order
98
+ class MessagePrinter
99
+ def initialize(container)
100
+ @message = container.resolve(:message)
101
+ @time = Time.now
102
+ end
103
+
104
+ def print
105
+ puts "#{@message} at #{@time}"
106
+ end
107
+ end
108
+
109
+ container.register(:message_printer, -> { MessagePrinter.new(container) }, memoize: true)
110
+ container.register(:message, 'Hello, world!')
111
+ container.resolve(:message_printer).print
112
+ # => Hello, world! at 2016-08-30 05:32:12 -0700
113
+
114
+ # Same instance is reused next time
115
+ container.resolve(:message_printer).print
116
+ # => Hello, world! at 2016-08-30 05:32:12 -0700
94
117
  ```
95
118
 
96
119
  You can also get container behaviour at both the class and instance level via the mixin:
@@ -15,6 +15,8 @@ Gem::Specification.new do |spec|
15
15
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
16
  spec.require_paths = ['lib']
17
17
 
18
+ spec.required_ruby_version = ">= 2.0.0"
19
+
18
20
  spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
19
21
  spec.add_runtime_dependency 'dry-configurable', '~> 0.1', '>= 0.1.3'
20
22
 
@@ -4,22 +4,41 @@ module Dry
4
4
  #
5
5
  # @private
6
6
  class Item
7
- attr_reader :item, :options
7
+ attr_reader :item, :options, :memoize, :memoize_mutex
8
8
 
9
9
  def initialize(item, options = {})
10
10
  @item = item
11
11
  @options = {
12
12
  call: item.is_a?(::Proc) && item.parameters.empty?
13
13
  }.merge(options)
14
+
15
+ if options[:memoize] == true
16
+ raise(
17
+ ::Dry::Container::Error,
18
+ 'Memoize only supported for a block or a proc'
19
+ ) unless item.is_a?(::Proc)
20
+ @memoize = true
21
+ @memoize_mutex = ::Mutex.new
22
+ end
14
23
  end
15
24
 
16
25
  def call
26
+ return memoized_item if memoize
27
+
17
28
  if options[:call] == true
18
29
  item.call
19
30
  else
20
31
  item
21
32
  end
22
33
  end
34
+
35
+ private
36
+
37
+ def memoized_item
38
+ memoize_mutex.synchronize do
39
+ @memoized_item ||= item.call
40
+ end
41
+ end
23
42
  end
24
43
  end
25
44
  end
@@ -1,7 +1,7 @@
1
1
  module Dry
2
2
  class Container
3
3
  PREFIX_NAMESPACE = ->(namespace, key, config) do
4
- [namespace, key].compact.join(config.namespace_separator)
4
+ [namespace, key].join(config.namespace_separator)
5
5
  end
6
6
  # Mixin to expose Inversion of Control (IoC) container behaviour
7
7
  #
@@ -125,16 +125,24 @@ module Dry
125
125
  #
126
126
  # @param [Dry::Container] other
127
127
  # The other container to merge in
128
+ # @param [Hash] options
129
+ # @option options [Symbol] :namespace
130
+ # Namespace to prefix other container items with, defaults to nil
128
131
  #
129
132
  # @return [Dry::Container::Mixin] self
130
133
  #
131
134
  # @api public
132
135
  def merge(other, namespace: nil)
133
- _container.merge!(
134
- other._container.each_with_object(::Concurrent::Hash.new) do |a, h|
135
- h[PREFIX_NAMESPACE.call(namespace, a.first, config)] = a.last
136
- end
137
- )
136
+ if namespace
137
+ _container.merge!(
138
+ other._container.each_with_object(::Concurrent::Hash.new) do |a, h|
139
+ h[PREFIX_NAMESPACE.call(namespace, a.first, config)] = a.last
140
+ end
141
+ )
142
+ else
143
+ _container.merge!(other._container)
144
+ end
145
+
138
146
  self
139
147
  end
140
148
 
@@ -21,7 +21,7 @@ module Dry
21
21
  # @option options [Symbol] :call
22
22
  # Whether the item should be called when resolved
23
23
  #
24
- # @raise [Dry::Conainer::Error]
24
+ # @raise [Dry::Container::Error]
25
25
  # If an item is already registered with the given key
26
26
  #
27
27
  # @return [Mixed]
@@ -1,6 +1,6 @@
1
1
  module Dry
2
2
  class Container
3
3
  # @api public
4
- VERSION = '0.4.0'.freeze
4
+ VERSION = '0.5.0'.freeze
5
5
  end
6
6
  end
@@ -185,6 +185,33 @@ shared_examples 'a container' do
185
185
  expect(container[:item].call).to eq('item')
186
186
  end
187
187
  end
188
+
189
+ context 'with option memoize: true' do
190
+ it 'registers and resolves a proc' do
191
+ container.register(:item, proc { 'item' }, memoize: true)
192
+
193
+ expect(container[:item]).to be container[:item]
194
+ expect(container.keys).to eq(['item'])
195
+ expect(container.key?(:item)).to be true
196
+ expect(container.resolve(:item)).to eq('item')
197
+ expect(container[:item]).to eq('item')
198
+ end
199
+
200
+ it 'only resolves the proc once' do
201
+ resolved_times = 0
202
+
203
+ container.register(:item, proc { resolved_times += 1 }, memoize: true)
204
+
205
+ expect(container.resolve(:item)).to be 1
206
+ expect(container.resolve(:item)).to be 1
207
+ end
208
+
209
+ context 'when receiving something other than a proc' do
210
+ it do
211
+ expect { container.register(:item, 'Hello!', memoize: true) }.to raise_error(Dry::Container::Error)
212
+ end
213
+ end
214
+ end
188
215
  end
189
216
 
190
217
  describe 'registering an object' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-container
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Holland
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-14 00:00:00.000000000 Z
11
+ date: 2016-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -99,6 +99,7 @@ files:
99
99
  - ".rubocop.yml"
100
100
  - ".rubocop_todo.yml"
101
101
  - ".travis.yml"
102
+ - CHANGELOG.md
102
103
  - Gemfile
103
104
  - LICENSE
104
105
  - README.md
@@ -132,7 +133,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
133
  requirements:
133
134
  - - ">="
134
135
  - !ruby/object:Gem::Version
135
- version: '0'
136
+ version: 2.0.0
136
137
  required_rubygems_version: !ruby/object:Gem::Requirement
137
138
  requirements:
138
139
  - - ">="
@@ -149,4 +150,3 @@ test_files:
149
150
  - spec/integration/mixin_spec.rb
150
151
  - spec/spec_helper.rb
151
152
  - spec/support/shared_examples/container.rb
152
- has_rdoc: