dry-container 0.5.0 → 0.8.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
- 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