dry-container 0.5.0 → 0.8.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
- SHA1:
3
- metadata.gz: 2f11ec3380a6ff086362780a67b687935cff8ddf
4
- data.tar.gz: 15db84953170fdc3f249d852d01d106f7a904f23
2
+ SHA256:
3
+ metadata.gz: 77e050044acc97600020d74da69d2b54a5788a61fcb84b7c9feba51068b2977e
4
+ data.tar.gz: d7aa97eea6849253f410414c12844f6c04baf4e4a3e9a58f2a26c0211f98ea89
5
5
  SHA512:
6
- metadata.gz: f36ffd98d0c80ffd158e1554a09dd89919aeb7c780010a276118ad217db89d9ace865746c18b97321b6022d75dc5a4e46523d27927cd01ee182d0bb3b6b105b8
7
- data.tar.gz: 7b52ee74e85b40edad15d082ad5fc64a20a00947a8d97d472be013f4f98fe363be5c25f007cd6d089582d0302034b35ed0041ce843e276c896100a9775a2a14a
6
+ metadata.gz: dd18bbb80600daf28c2ce1ce5ea4a24c688a1cfd7e21b365e3486cb871d5cd2065f4484123b0c5d016a9e637fb4fdc44208c6884bb4fd24a241e7c43d26175cd
7
+ data.tar.gz: 19d157a7db948b4663b9ced4d5db537cd0b43407afd8e8e852b203202863f8eba279a083d6d302b8cbe05899e5036b24465186683b8d5746f3fc63d3a5debfeb
data/CHANGELOG.md CHANGED
@@ -1,11 +1,98 @@
1
- ## v0.5.0
1
+ <!--- DO NOT EDIT THIS FILE - IT'S AUTOMATICALLY GENERATED VIA DEVTOOLS --->
2
2
 
3
- ## Added
3
+ ## 0.7.2 2019-07-09
4
4
 
5
- * `memoize` option to `#register` - memoizes items on first resolve ([ivoanjo](https://github.com/ivoanjo))
6
5
 
7
- ## Fixed
6
+ ### Added
8
7
 
9
- * `required_ruby_version` set to `>= 2.0.0` ([artofhuman](https://github.com/artofhuman))
8
+ - `.resolve` accepts an optional fallback block, similar to how `Hash#fetch` works ([flash-gordon](https://github.com/flash-gordon))
9
+ ```ruby
10
+ container.resolve('missing_key') { :fallback } # => :fallback
11
+ ```
12
+ - `.decorate` can (again) work with static values. Also, it can take a block instead of `with` ([flash-gordon](https://github.com/flash-gordon))
13
+ ```ruby
14
+ container.register('key', 'value')
15
+ container.decorate('key') { |v| "<'#{v}'>" }
16
+ container.resolve('key') # => "<'value'>"
17
+ ```
10
18
 
11
- [Compare v0.4.0...HEAD](https://github.com/dry-rb/dry-container/compare/v0.4.0...HEAD)
19
+
20
+ [Compare v0.7.1...v0.7.2](https://github.com/dry-rb/dry-container/compare/v0.7.1...v0.7.2)
21
+
22
+ ## 0.7.1 2019-06-07
23
+
24
+
25
+ ### Fixed
26
+
27
+ - Added `Mixin#dup` and `Mixin#clone`, now copies don't share underlying containers (flash-gordon)
28
+
29
+
30
+ [Compare v0.7.0...v0.7.1](https://github.com/dry-rb/dry-container/compare/v0.7.0...v0.7.1)
31
+
32
+ ## 0.7.0 2019-02-05
33
+
34
+
35
+ ### Added
36
+
37
+ - Namespace DSL resolves keys relative to the current namespace, see the corresponding [changes](https://github.com/dry-rb/dry-container/pull/47) ([yuszuv](https://github.com/yuszuv))
38
+ - Registered objects can be decorated with the following API ([igor-alexandrov](https://github.com/igor-alexandrov))
39
+
40
+ ```ruby
41
+ class CreateUser
42
+ def call(params)
43
+ # ...
44
+ end
45
+ end
46
+ container.register('create_user') { CreateUser.new }
47
+ container.decorate('create_user', with: ShinyLogger.new)
48
+
49
+ # Now subsequent resolutions will return a wrapped object
50
+
51
+ container.resolve('create_user')
52
+ # => #<ShinyLogger @obj=#<CreateUser:0x...>]>
53
+ ```
54
+ - Freezing a container now prevents further registrations ([flash-gordon](https://github.com/flash-gordon))
55
+ - ## Internal
56
+ - Handling container items was generalized in [#34](https://github.com/dry-rb/dry-container/pull/34) ([GabrielMalakias](https://github.com/GabrielMalakias))
57
+
58
+ ### Fixed
59
+
60
+ - Symbols are now coerced to strings when resolving stubbed dependencies ([cthulhu666](https://github.com/cthulhu666))
61
+ - Stubbing keys not present in container will raise an error ([flash-gordon](https://github.com/flash-gordon))
62
+
63
+ This means after upgrading you may see errors like this
64
+ ```
65
+ ArgumentError (cannot stub "something" - no such key in container)
66
+ ```
67
+ Be sure you register dependencies before using them. The new behavior will likely save quite a bit of time when debugging ill-configured container setups.
68
+
69
+ ### Changed
70
+
71
+ - [BREAKING] Now only Ruby 2.3 and above is supported ([flash-gordon](https://github.com/flash-gordon))
72
+
73
+ [Compare v0.6.0...v0.7.0](https://github.com/dry-rb/dry-container/compare/v0.6.0...v0.7.0)
74
+
75
+ ## 0.6.0 2016-12-09
76
+
77
+
78
+ ### Added
79
+
80
+ - `Dry::Container::Mixin#each` - provides a means of seeing what all is registered in the container ([jeremyf](https://github.com/jeremyf))
81
+
82
+ ### Fixed
83
+
84
+ - Including mixin into a class with a custom initializer ([maltoe](https://github.com/maltoe))
85
+
86
+
87
+ [Compare v0.5.0...v0.6.0](https://github.com/dry-rb/dry-container/compare/v0.5.0...v0.6.0)
88
+
89
+ ## 0.5.0 2016-08-31
90
+
91
+
92
+ ### Added
93
+
94
+ - `memoize` option to `#register` - memoizes items on first resolve ([ivoanjo](https://github.com/ivoanjo))
95
+
96
+ ### Fixed
97
+
98
+ - `required_ruby_version` set to `>= 2.0.0` ([artofhuman](https://github.com/artofhuman))
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014 Ruby Object Mapper
3
+ Copyright (c) 2015-2021 dry-rb team
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
data/README.md CHANGED
@@ -1,169 +1,29 @@
1
- [gitter]: https://gitter.im/dry-rb/chat
1
+ <!--- this file is synced from dry-rb/template-gem project -->
2
2
  [gem]: https://rubygems.org/gems/dry-container
3
- [travis]: https://travis-ci.org/dry-rb/dry-container
4
- [code_climate]: https://codeclimate.com/github/dry-rb/dry-container
5
- [inch]: http://inch-ci.org/github/dry-rb/dry-container
3
+ [actions]: https://github.com/dry-rb/dry-container/actions
4
+ [codacy]: https://www.codacy.com/gh/dry-rb/dry-container
5
+ [chat]: https://dry-rb.zulipchat.com
6
+ [inchpages]: http://inch-ci.org/github/dry-rb/dry-container
6
7
 
7
- # dry-container [![Join the Gitter chat](https://badges.gitter.im/Join%20Chat.svg)][gitter]
8
+ # dry-container [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
8
9
 
9
- [![Gem Version](https://img.shields.io/gem/v/dry-container.svg)][gem]
10
- [![Build Status](https://img.shields.io/travis/dry-rb/dry-container.svg)][travis]
11
- [![Code Climate](https://img.shields.io/codeclimate/github/dry-rb/dry-container.svg)][code_climate]
12
- [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/dry-rb/dry-container.svg)][code_climate]
13
- [![API Documentation Coverage](http://inch-ci.org/github/dry-rb/dry-container.svg)][inch]
10
+ [![Gem Version](https://badge.fury.io/rb/dry-container.svg)][gem]
11
+ [![CI Status](https://github.com/dry-rb/dry-container/workflows/ci/badge.svg)][actions]
12
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/227509c9034340b493f769f6277f4ecb)][codacy]
13
+ [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/227509c9034340b493f769f6277f4ecb)][codacy]
14
+ [![Inline docs](http://inch-ci.org/github/dry-rb/dry-container.svg?branch=master)][inchpages]
14
15
 
16
+ ## Links
15
17
 
16
- A simple, configurable container implemented in Ruby
18
+ * [User documentation](https://dry-rb.org/gems/dry-container)
19
+ * [API documentation](http://rubydoc.info/gems/dry-container)
17
20
 
18
- ## Synopsis
21
+ ## Supported Ruby versions
19
22
 
20
- ### Brief Example
23
+ This library officially supports the following Ruby versions:
21
24
 
22
- ```ruby
23
- container = Dry::Container.new
24
- container.register(:parrot) { |a| puts a }
25
-
26
- parrot = container.resolve(:parrot)
27
- parrot.call("Hello World")
28
- # Hello World
29
- # => nil
30
- ```
31
-
32
- ### Detailed Example
33
-
34
- ```ruby
35
- User = Struct.new(:name, :email)
36
-
37
- data_store = Concurrent::Map.new.tap do |ds|
38
- ds[:users] = Concurrent::Array.new
39
- end
40
-
41
- # Initialize container
42
- container = Dry::Container.new
43
-
44
- # Register an item with the container to be resolved later
45
- container.register(:data_store, data_store)
46
- container.register(:user_repository, -> { container.resolve(:data_store)[:users] })
47
-
48
- # Resolve an item from the container
49
- container.resolve(:user_repository) << User.new('Jack', 'jack@dry-container.com')
50
- # You can also resolve with []
51
- container[:user_repository] << User.new('Jill', 'jill@dry-container.com')
52
- # => [
53
- # #<struct User name="Jack", email="jack@dry-container.com">,
54
- # #<struct User name="Jill", email="jill@dry-container.com">
55
- # ]
56
-
57
- # If you wish to register an item that responds to call but don't want it to be
58
- # called when resolved, you can use the options hash
59
- container.register(:proc, -> { :result }, call: false)
60
- container.resolve(:proc)
61
- # => #<Proc:0x007fa75e652c98@(irb):25 (lambda)>
62
-
63
- # You can also register using a block
64
- container.register(:item) do
65
- :result
66
- end
67
- container.resolve(:item)
68
- # => :result
69
-
70
- container.register(:block, call: false) do
71
- :result
72
- end
73
- container.resolve(:block)
74
- # => #<Proc:0x007fa75e6830f0@(irb):36>
75
-
76
- # You can also register items under namespaces using the #namespace method
77
- container.namespace('repositories') do
78
- namespace('checkout') do
79
- register('orders') { Concurrent::Array.new }
80
- end
81
- end
82
- container.resolve('repositories.checkout.orders')
83
- # => []
84
-
85
- # Or import a namespace
86
- ns = Dry::Container::Namespace.new('repositories') do
87
- namespace('authentication') do
88
- register('users') { Concurrent::Array.new }
89
- end
90
- end
91
- container.import(ns)
92
- container.resolve('repositories.authentication.users')
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
117
- ```
118
-
119
- You can also get container behaviour at both the class and instance level via the mixin:
120
-
121
- ```ruby
122
- class Container
123
- extend Dry::Container::Mixin
124
- end
125
- Container.register(:item, :my_item)
126
- Container.resolve(:item)
127
- # => :my_item
128
-
129
- class ContainerObject
130
- include Dry::Container::Mixin
131
- end
132
- container = ContainerObject.new
133
- container.register(:item, :my_item)
134
- container.resolve(:item)
135
- # => :my_item
136
- ```
137
- ### Using a custom registry/resolver
138
-
139
- You can configure how items are registered and resolved from the container:
140
-
141
- ```ruby
142
- Dry::Container.configure do |config|
143
- config.registry = ->(container, key, item, options) { container[key] = item }
144
- config.resolver = ->(container, key) { container[key] }
145
- end
146
-
147
- class Container
148
- extend Dry::Container::Mixin
149
-
150
- configure do |config|
151
- config.registry = ->(container, key, item, options) { container[key] = item }
152
- config.resolver = ->(container, key) { container[key] }
153
- end
154
- end
155
-
156
- class ContainerObject
157
- include Dry::Container::Mixin
158
-
159
- configure do |config|
160
- config.registry = ->(container, key, item, options) { container[key] = item }
161
- config.resolver = ->(container, key) { container[key] }
162
- end
163
- end
164
- ```
165
-
166
- This allows you to customise the behaviour of Dry::Container, for example, the default registry (Dry::Container::Registry) will raise a Dry::Container::Error exception if you try to register under a key that is already used, you may want to just overwrite the existing value in that scenario, configuration allows you to do so.
25
+ * MRI `>= 2.6.0`
26
+ * jruby `>= 9.2`
167
27
 
168
28
  ## License
169
29
 
@@ -1,26 +1,42 @@
1
- # coding: utf-8
2
- require File.expand_path('../lib/dry/container/version', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ # this file is synced from dry-rb/template-gem project
4
+
5
+ lib = File.expand_path("lib", __dir__)
6
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
+ require "dry/container/version"
3
8
 
4
9
  Gem::Specification.new do |spec|
5
- spec.name = 'dry-container'
6
- spec.version = ::Dry::Container::VERSION
7
- spec.authors = ['Andy Holland']
8
- spec.email = ['andyholland1991@aol.com']
9
- spec.summary = 'A simple container intended for use as an IoC container'
10
- spec.homepage = 'https://github.com/dryrb/dry-container'
11
- spec.license = 'MIT'
12
-
13
- spec.files = `git ls-files -z`.split("\x0")
14
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
16
- spec.require_paths = ['lib']
17
-
18
- spec.required_ruby_version = ">= 2.0.0"
19
-
20
- spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
21
- spec.add_runtime_dependency 'dry-configurable', '~> 0.1', '>= 0.1.3'
22
-
23
- spec.add_development_dependency 'bundler'
24
- spec.add_development_dependency 'rake'
25
- spec.add_development_dependency 'rspec'
10
+ spec.name = "dry-container"
11
+ spec.authors = ["Andy Holland"]
12
+ spec.email = ["andyholland1991@aol.com"]
13
+ spec.license = "MIT"
14
+ spec.version = Dry::Container::VERSION.dup
15
+
16
+ spec.summary = "A simple, configurable object container implemented in Ruby"
17
+ spec.description = spec.summary
18
+ spec.homepage = "https://dry-rb.org/gems/dry-container"
19
+ spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-container.gemspec", "lib/**/*"]
20
+ spec.bindir = "bin"
21
+ spec.executables = []
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
25
+ spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-container/blob/master/CHANGELOG.md"
26
+ spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-container"
27
+ spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-container/issues"
28
+
29
+ if defined? JRUBY_VERSION
30
+ spec.required_ruby_version = ">= 2.5.0"
31
+ else
32
+ spec.required_ruby_version = ">= 2.6.0"
33
+ end
34
+
35
+ # to update dependencies edit project.yml
36
+ spec.add_runtime_dependency "concurrent-ruby", "~> 1.0"
37
+ spec.add_runtime_dependency "dry-configurable", "~> 0.1", ">= 0.1.3"
38
+
39
+ spec.add_development_dependency "bundler"
40
+ spec.add_development_dependency "rake"
41
+ spec.add_development_dependency "rspec"
26
42
  end
data/lib/dry-container.rb CHANGED
@@ -1 +1,3 @@
1
- require 'dry/container'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/container"
data/lib/dry/container.rb CHANGED
@@ -1,13 +1,13 @@
1
- require 'concurrent'
2
- require 'dry-configurable'
3
- require 'dry/container/error'
4
- require 'dry/container/item'
5
- require 'dry/container/namespace'
6
- require 'dry/container/registry'
7
- require 'dry/container/resolver'
8
- require 'dry/container/namespace_dsl'
9
- require 'dry/container/mixin'
10
- require 'dry/container/version'
1
+ # frozen_string_literal: true
2
+
3
+ require "dry-configurable"
4
+ require "dry/container/error"
5
+ require "dry/container/namespace"
6
+ require "dry/container/registry"
7
+ require "dry/container/resolver"
8
+ require "dry/container/namespace_dsl"
9
+ require "dry/container/mixin"
10
+ require "dry/container/version"
11
11
 
12
12
  # A collection of micro-libraries, each intended to encapsulate
13
13
  # a common task in Ruby
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  class Container
3
5
  # @api public
4
- class Error < ::StandardError; end
6
+ Error = Class.new(StandardError)
5
7
  end
6
8
  end
@@ -1,42 +1,49 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dry
2
4
  class Container
3
- # Container class
5
+ # Base class to abstract Memoizable and Callable implementations
6
+ #
7
+ # @api abstract
4
8
  #
5
- # @private
6
9
  class Item
7
- attr_reader :item, :options, :memoize, :memoize_mutex
10
+ # @return [Mixed] the item to be solved later
11
+ attr_reader :item
12
+
13
+ # @return [Hash] the options to memoize, call or no.
14
+ attr_reader :options
8
15
 
16
+ # @api abstract
9
17
  def initialize(item, options = {})
10
18
  @item = item
11
19
  @options = {
12
20
  call: item.is_a?(::Proc) && item.parameters.empty?
13
21
  }.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
23
22
  end
24
23
 
24
+ # @api abstract
25
25
  def call
26
- return memoized_item if memoize
26
+ raise NotImplementedError
27
+ end
27
28
 
28
- if options[:call] == true
29
- item.call
30
- else
31
- item
32
- end
29
+ # @private
30
+ def value?
31
+ !callable?
33
32
  end
34
33
 
35
- private
34
+ # @private
35
+ def callable?
36
+ options[:call]
37
+ end
36
38
 
37
- def memoized_item
38
- memoize_mutex.synchronize do
39
- @memoized_item ||= item.call
39
+ # Build a new item with transformation applied
40
+ #
41
+ # @private
42
+ def map(func)
43
+ if callable?
44
+ self.class.new(-> { func.(item.call) }, options)
45
+ else
46
+ self.class.new(func.(item), options)
40
47
  end
41
48
  end
42
49
  end