dry-auto_inject 0.6.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,7 @@ module Dry
5
5
  DuplicateDependencyError = Class.new(StandardError)
6
6
  DependencyNameInvalid = Class.new(StandardError)
7
7
 
8
- VALID_NAME = /([a-z_][a-zA-Z_0-9]*)$/
8
+ VALID_NAME = /([a-z_][a-zA-Z_0-9]*)$/.freeze
9
9
 
10
10
  class DependencyMap
11
11
  def initialize(*dependencies)
@@ -29,7 +29,7 @@ module Dry
29
29
  end
30
30
 
31
31
  def names
32
- @name ||= @map.keys
32
+ @names ||= @map.keys
33
33
  end
34
34
 
35
35
  def to_h
@@ -41,13 +41,18 @@ module Dry
41
41
 
42
42
  def name_for(identifier)
43
43
  matched = VALID_NAME.match(identifier.to_s)
44
- raise DependencyNameInvalid, "name +#{identifier}+ is not a valid Ruby identifier" unless matched
44
+ unless matched
45
+ raise DependencyNameInvalid,
46
+ "name +#{identifier}+ is not a valid Ruby identifier"
47
+ end
48
+
45
49
  matched[0]
46
50
  end
47
51
 
48
52
  def add_dependency(name, identifier)
49
53
  name = name.to_sym
50
54
  raise DuplicateDependencyError, "name +#{name}+ is already used" if @map.key?(name)
55
+
51
56
  @map[name] = identifier
52
57
  end
53
58
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/auto_inject/strategies'
3
+ require "dry/auto_inject/strategies"
4
4
 
5
5
  module Dry
6
6
  module AutoInject
@@ -14,6 +14,8 @@ module Dry
14
14
  # @api private
15
15
  attr_reader :builder
16
16
 
17
+ define_method(:respond_to?, ::Kernel.instance_method(:respond_to?))
18
+
17
19
  # @api private
18
20
  def initialize(container, strategy, builder:)
19
21
  @container = container
@@ -25,13 +27,13 @@ module Dry
25
27
  strategy.new(container, *dependency_names)
26
28
  end
27
29
 
28
- def respond_to?(name, include_private = false)
29
- Injector.instance_methods.include?(name) || builder.respond_to?(name)
30
+ def respond_to_missing?(name, _include_private = false)
31
+ builder.respond_to?(name)
30
32
  end
31
33
 
32
34
  private
33
35
 
34
- def method_missing(name, *args, &block)
36
+ def method_missing(name, *_args)
35
37
  builder.__send__(name)
36
38
  end
37
39
  end
@@ -1,47 +1,25 @@
1
- require 'set'
1
+ # frozen_string_literal: true
2
+
3
+ require "set"
2
4
 
3
5
  module Dry
4
6
  module AutoInject
5
7
  # @api private
6
8
  class MethodParameters
7
- PASS_THROUGH = [[:rest]]
8
-
9
- if RUBY_VERSION >= '2.4.4.' && !defined? JRUBY_VERSION
10
- def self.of(obj, name)
11
- Enumerator.new do |y|
12
- begin
13
- method = obj.instance_method(name)
14
- rescue NameError
15
- end
16
-
17
- loop do
18
- break if method.nil?
19
-
20
- y << MethodParameters.new(method.parameters)
21
- method = method.super_method
22
- end
9
+ PASS_THROUGH = [[%i[rest]], [%i[rest], %i[keyrest]]].freeze
10
+
11
+ def self.of(obj, name)
12
+ Enumerator.new do |y|
13
+ begin
14
+ method = obj.instance_method(name)
15
+ rescue ::NameError # rubocop: disable Lint/SuppressedException
23
16
  end
24
- end
25
- else
26
- # see https://bugs.ruby-lang.org/issues/13973
27
- def self.of(obj, name)
28
- Enumerator.new do |y|
29
- ancestors = obj.ancestors
30
-
31
- loop do
32
- klass = ancestors.shift
33
- break if klass.nil?
34
-
35
- begin
36
- method = klass.instance_method(name)
37
-
38
- next unless method.owner.equal?(klass)
39
- rescue NameError
40
- next
41
- end
42
-
43
- y << MethodParameters.new(method.parameters)
44
- end
17
+
18
+ loop do
19
+ break if method.nil?
20
+
21
+ y << MethodParameters.new(method.parameters)
22
+ method = method.super_method
45
23
  end
46
24
  end
47
25
  end
@@ -54,11 +32,13 @@ module Dry
54
32
 
55
33
  def splat?
56
34
  return @splat if defined? @splat
35
+
57
36
  @splat = parameters.any? { |type, _| type == :rest }
58
37
  end
59
38
 
60
39
  def sequential_arguments?
61
40
  return @sequential_arguments if defined? @sequential_arguments
41
+
62
42
  @sequential_arguments = parameters.any? { |type, _|
63
43
  type == :req || type == :opt
64
44
  }
@@ -83,7 +63,7 @@ module Dry
83
63
  end
84
64
 
85
65
  def pass_through?
86
- parameters.eql?(PASS_THROUGH)
66
+ PASS_THROUGH.include?(parameters)
87
67
  end
88
68
 
89
69
  EMPTY = new([])
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/auto_inject/strategies/constructor'
4
- require 'dry/auto_inject/method_parameters'
3
+ require "dry/auto_inject/strategies/constructor"
4
+ require "dry/auto_inject/method_parameters"
5
5
 
6
6
  module Dry
7
7
  module AutoInject
@@ -17,7 +17,7 @@ module Dry
17
17
  args[i] || container[identifier]
18
18
  }
19
19
 
20
- super(*deps, *args[deps.size..-1])
20
+ super(*deps, *args[deps.size..])
21
21
  end
22
22
  end
23
23
  end
@@ -36,28 +36,35 @@ module Dry
36
36
  end
37
37
 
38
38
  def define_initialize_with_params
39
- initialize_args = dependency_map.names.join(', ')
39
+ initialize_args = dependency_map.names.join(", ")
40
+
41
+ assignment = dependency_map.names.map { "@#{_1} = #{_1}" }.join("\n")
40
42
 
41
43
  instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
42
- def initialize(#{initialize_args})
43
- #{dependency_map.names.map { |name| "@#{name} = #{name}" }.join("\n")}
44
- super()
45
- end
44
+ def initialize(#{initialize_args}) # def initialize(dep)
45
+ #{assignment} # @dep = dep
46
+ super() # super()
47
+ end # end
46
48
  RUBY
47
49
  end
48
50
 
49
51
  def define_initialize_with_splat(super_parameters)
50
52
  super_pass = if super_parameters.splat?
51
- '*args'
52
- else
53
- "*args.take(#{super_parameters.length})"
53
+ "*args"
54
+ else
55
+ "*args.take(#{super_parameters.length})"
56
+ end
57
+
58
+ assignments = dependency_map.names.map.with_index do |name, idx|
59
+ "@#{name} = args[#{idx}]"
54
60
  end
61
+ body = assignments.join("\n")
55
62
 
56
63
  instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
57
- def initialize(*args)
58
- #{dependency_map.names.map.with_index { |name, i| "@#{name} = args[#{i}]" }.join("\n")}
59
- super(#{super_pass})
60
- end
64
+ def initialize(*args) # def initialize(*args)
65
+ #{body} # @dep = args[0]
66
+ super(#{super_pass}) # super(*args)
67
+ end # end
61
68
  RUBY
62
69
  end
63
70
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/auto_inject/dependency_map'
3
+ require "dry/auto_inject/dependency_map"
4
4
 
5
5
  module Dry
6
6
  module AutoInject
@@ -15,6 +15,7 @@ module Dry
15
15
  attr_reader :class_mod
16
16
 
17
17
  def initialize(container, *dependency_names)
18
+ super()
18
19
  @container = container
19
20
  @dependency_map = DependencyMap.new(*dependency_names)
20
21
  @instance_mod = InstanceMethods.new
@@ -37,8 +38,9 @@ module Dry
37
38
  private
38
39
 
39
40
  def define_readers
41
+ readers = dependency_map.names.map { ":#{_1}" }
40
42
  instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
41
- attr_reader #{dependency_map.names.map { |name| ":#{name}" }.join(', ')}
43
+ attr_reader #{readers.join(", ")} # attr_reader :dep1, :dep2
42
44
  RUBY
43
45
  self
44
46
  end
@@ -47,7 +49,7 @@ module Dry
47
49
  raise NotImplementedError, "must be implemented by a subclass"
48
50
  end
49
51
 
50
- def define_initialize(klass)
52
+ def define_initialize(_klass)
51
53
  raise NotImplementedError, "must be implemented by a subclass"
52
54
  end
53
55
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/auto_inject/strategies/constructor'
4
- require 'dry/auto_inject/method_parameters'
3
+ require "dry/auto_inject/strategies/constructor"
4
+ require "dry/auto_inject/method_parameters"
5
5
 
6
6
  module Dry
7
7
  module AutoInject
@@ -24,13 +24,23 @@ module Dry
24
24
 
25
25
  def define_initialize(klass)
26
26
  super_params = MethodParameters.of(klass, :initialize).first
27
- super_pass = super_params.empty? ? '' : 'options'
27
+ super_pass = super_params.empty? ? "" : "options"
28
+ assignments = dependency_map.names.map do |name|
29
+ <<~RUBY
30
+ unless !options.key?(:#{name}) && instance_variable_defined?(:'@#{name}')
31
+ @#{name} = options[:#{name}]
32
+ end
33
+ RUBY
34
+ end
35
+ body = assignments.join("\n")
28
36
 
29
37
  instance_mod.class_eval <<-RUBY, __FILE__, __LINE__ + 1
30
- def initialize(options)
31
- #{dependency_map.names.map { |name| "@#{name} = options[:#{name}] unless !options.key?(#{name}) && instance_variable_defined?(:'@#{name}')" }.join("\n")}
32
- super(#{super_pass})
33
- end
38
+ def initialize(options) # def initialize(options)
39
+ # unless !options.key?(:dep) && instance_variable_defined?(:@dep)
40
+ #{body} # @dep = options[:dep]
41
+ # end
42
+ super(#{super_pass}) # super(options)
43
+ end # end
34
44
  RUBY
35
45
  end
36
46
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/auto_inject/strategies/constructor'
4
- require 'dry/auto_inject/method_parameters'
3
+ require "dry/auto_inject/strategies/constructor"
4
+ require "dry/auto_inject/method_parameters"
5
5
 
6
6
  module Dry
7
7
  module AutoInject
@@ -14,19 +14,20 @@ module Dry
14
14
  class_mod.class_exec(container, dependency_map) do |container, dependency_map|
15
15
  map = dependency_map.to_h
16
16
 
17
- define_method :new do |*args, **kwargs|
17
+ define_method :new do |*args, **kwargs, &block|
18
18
  map.each do |name, identifier|
19
- kwargs[name] ||= container[identifier]
19
+ kwargs[name] = container[identifier] unless kwargs.key?(name)
20
20
  end
21
21
 
22
- super(*args, **kwargs)
22
+ super(*args, **kwargs, &block)
23
23
  end
24
24
  end
25
25
  end
26
26
 
27
27
  def define_initialize(klass)
28
28
  super_parameters = MethodParameters.of(klass, :initialize).each do |ps|
29
- # Look upwards past `def foo(*)` methods until we get an explicit list of parameters
29
+ # Look upwards past `def foo(*)` and `def foo(...)` methods
30
+ # until we get an explicit list of parameters
30
31
  break ps unless ps.pass_through?
31
32
  end
32
33
 
@@ -44,15 +45,15 @@ module Dry
44
45
  slice_kwargs = method(:slice_kwargs)
45
46
 
46
47
  instance_mod.class_exec do
47
- define_method :initialize do |**kwargs|
48
+ define_method :initialize do |**kwargs, &block|
48
49
  assign_dependencies.(kwargs, self)
49
50
 
50
51
  super_kwargs = slice_kwargs.(kwargs, super_parameters)
51
52
 
52
53
  if super_kwargs.any?
53
- super(super_kwargs)
54
+ super(**super_kwargs, &block)
54
55
  else
55
- super()
56
+ super(&block)
56
57
  end
57
58
  end
58
59
  end
@@ -63,18 +64,18 @@ module Dry
63
64
  slice_kwargs = method(:slice_kwargs)
64
65
 
65
66
  instance_mod.class_exec do
66
- define_method :initialize do |*args, **kwargs|
67
+ define_method :initialize do |*args, **kwargs, &block|
67
68
  assign_dependencies.(kwargs, self)
68
69
 
69
70
  if super_parameters.splat?
70
- super(*args, kwargs)
71
+ super(*args, **kwargs, &block)
71
72
  else
72
73
  super_kwargs = slice_kwargs.(kwargs, super_parameters)
73
74
 
74
75
  if super_kwargs.any?
75
- super(*args, super_kwargs)
76
+ super(*args, **super_kwargs, &block)
76
77
  else
77
- super(*args)
78
+ super(*args, &block)
78
79
  end
79
80
  end
80
81
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry-container'
3
+ require "dry-container"
4
4
 
5
5
  module Dry
6
6
  module AutoInject
@@ -16,6 +16,6 @@ module Dry
16
16
  end
17
17
  end
18
18
 
19
- require 'dry/auto_inject/strategies/args'
20
- require 'dry/auto_inject/strategies/hash'
21
- require 'dry/auto_inject/strategies/kwargs'
19
+ require "dry/auto_inject/strategies/args"
20
+ require "dry/auto_inject/strategies/hash"
21
+ require "dry/auto_inject/strategies/kwargs"
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module AutoInject
5
- VERSION = '0.6.0'
5
+ VERSION = "0.9.0"
6
6
  end
7
7
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/auto_inject/builder'
3
+ require "dry/auto_inject/builder"
4
4
 
5
5
  module Dry
6
6
  # Configure an auto-injection module
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'dry/auto_inject'
3
+ require "dry/auto_inject"
metadata CHANGED
@@ -1,92 +1,81 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-auto_inject
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
- autorequire:
9
- bindir: exe
8
+ autorequire:
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-29 00:00:00.000000000 Z
11
+ date: 2022-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
+ name: dry-container
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
17
  - - ">="
17
18
  - !ruby/object:Gem::Version
18
19
  version: 0.3.4
19
- name: dry-container
20
- prerelease: false
21
20
  type: :runtime
21
+ prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.3.4
27
27
  - !ruby/object:Gem::Dependency
28
+ name: bundler
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
31
  - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
- name: bundler
34
- prerelease: false
35
34
  type: :development
35
+ prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
+ name: rake
42
43
  requirement: !ruby/object:Gem::Requirement
43
44
  requirements:
44
45
  - - ">="
45
46
  - !ruby/object:Gem::Version
46
47
  version: '0'
47
- name: rake
48
- prerelease: false
49
48
  type: :development
49
+ prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
+ name: rspec
56
57
  requirement: !ruby/object:Gem::Requirement
57
58
  requirements:
58
- - - "~>"
59
+ - - ">="
59
60
  - !ruby/object:Gem::Version
60
- version: '3.8'
61
- name: rspec
62
- prerelease: false
61
+ version: '0'
63
62
  type: :development
63
+ prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '3.8'
69
- description:
68
+ version: '0'
69
+ description: Container-agnostic automatic constructor injection
70
70
  email:
71
71
  - piotr.solnica@gmail.com
72
72
  executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
- - ".codeclimate.yml"
77
- - ".gitignore"
78
- - ".rspec"
79
- - ".rubocop.yml"
80
- - ".rubocop_todo.yml"
81
- - ".travis.yml"
82
76
  - CHANGELOG.md
83
- - CONTRIBUTING.md
84
- - Gemfile
85
77
  - LICENSE
86
78
  - README.md
87
- - Rakefile
88
- - bin/console
89
- - bin/setup
90
79
  - dry-auto_inject.gemspec
91
80
  - lib/dry-auto_inject.rb
92
81
  - lib/dry/auto_inject.rb
@@ -100,12 +89,15 @@ files:
100
89
  - lib/dry/auto_inject/strategies/hash.rb
101
90
  - lib/dry/auto_inject/strategies/kwargs.rb
102
91
  - lib/dry/auto_inject/version.rb
103
- - rakelib/rubocop.rake
104
- homepage: https://github.com/dryrb/dry-auto_inject
92
+ homepage: https://dry-rb.org/gems/dry-auto_inject
105
93
  licenses:
106
94
  - MIT
107
- metadata: {}
108
- post_install_message:
95
+ metadata:
96
+ allowed_push_host: https://rubygems.org
97
+ changelog_uri: https://github.com/dry-rb/dry-auto_inject/blob/master/CHANGELOG.md
98
+ source_code_uri: https://github.com/dry-rb/dry-auto_inject
99
+ bug_tracker_uri: https://github.com/dry-rb/dry-auto_inject/issues
100
+ post_install_message:
109
101
  rdoc_options: []
110
102
  require_paths:
111
103
  - lib
@@ -113,16 +105,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
105
  requirements:
114
106
  - - ">="
115
107
  - !ruby/object:Gem::Version
116
- version: 2.3.0
108
+ version: 2.7.0
117
109
  required_rubygems_version: !ruby/object:Gem::Requirement
118
110
  requirements:
119
111
  - - ">="
120
112
  - !ruby/object:Gem::Version
121
113
  version: '0'
122
114
  requirements: []
123
- rubyforge_project:
124
- rubygems_version: 2.7.6
125
- signing_key:
115
+ rubygems_version: 3.1.6
116
+ signing_key:
126
117
  specification_version: 4
127
118
  summary: Container-agnostic automatic constructor injection
128
119
  test_files: []
data/.codeclimate.yml DELETED
@@ -1,6 +0,0 @@
1
- engines:
2
- rubocop:
3
- enabled: true
4
- ratings:
5
- paths:
6
- - lib/**
data/.gitignore DELETED
@@ -1,10 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /vendor/
6
- /coverage/
7
- /doc/
8
- /pkg/
9
- /spec/reports/
10
- /tmp/
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,19 +0,0 @@
1
- # Generated by `rubocop --auto-gen-config`
2
- inherit_from: .rubocop_todo.yml
3
-
4
- Metrics/LineLength:
5
- Max: 110
6
-
7
- Lint/HandleExceptions:
8
- Exclude:
9
- - rakelib/*.rake
10
-
11
- Style/LambdaCall:
12
- EnforcedStyle: braces
13
-
14
- Style/Documentation:
15
- Enabled: false
16
-
17
- Style/FileName:
18
- Exclude:
19
- - lib/dry-pipeline.rb
data/.rubocop_todo.yml DELETED
@@ -1,6 +0,0 @@
1
- # This configuration was generated by `rubocop --auto-gen-config`
2
- # on 2015-08-19 22:11:28 +0100 using RuboCop version 0.32.0.
3
- # The point is for the user to remove these configuration records
4
- # one by one as the offenses are removed from the code base.
5
- # Note that changes in the inspected code, or installation of new
6
- # versions of RuboCop, may require this file to be generated again.
data/.travis.yml DELETED
@@ -1,23 +0,0 @@
1
- language: ruby
2
- cache: bundler
3
- bundler_args: --without tools
4
- script:
5
- - bundle exec rake
6
- after_success:
7
- - '[ -d coverage ] && bundle exec codeclimate-test-reporter'
8
- rvm:
9
- - 2.5.3
10
- - 2.4.5
11
- - 2.3.8
12
- - jruby-9.2.4.1
13
- env:
14
- global:
15
- - COVERAGE=true
16
- notifications:
17
- email: false
18
- webhooks:
19
- urls:
20
- - https://webhooks.gitter.im/e/19098b4253a72c9796db
21
- on_success: change # options: [always|never|change] default: always
22
- on_failure: always # options: [always|never|change] default: always
23
- on_start: false # default: false
data/CONTRIBUTING.md DELETED
@@ -1,29 +0,0 @@
1
- # Issue Guidelines
2
-
3
- ## Reporting bugs
4
-
5
- If you found a bug, report an issue and describe what's the expected behavior versus what actually happens. If the bug causes a crash, attach a full backtrace. If possible, a reproduction script showing the problem is highly appreciated.
6
-
7
- ## Reporting feature requests
8
-
9
- Report a feature request **only after discussing it first on [discuss.dry-rb.org](https://discuss.dry-rb.org)** where it was accepted. Please provide a concise description of the feature, don't link to a discussion thread, and instead summarize what was discussed.
10
-
11
- ## Reporting questions, support requests, ideas, concerns etc.
12
-
13
- **PLEASE DON'T** - use [discuss.dry-rb.org](http://discuss.dry-rb.org) instead.
14
-
15
- # Pull Request Guidelines
16
-
17
- A Pull Request will only be accepted if it addresses a specific issue that was reported previously, or fixes typos, mistakes in documentation etc.
18
-
19
- Other requirements:
20
-
21
- 1) Do not open a pull request if you can't provide tests along with it. If you have problems writing tests, ask for help in the related issue.
22
- 2) Follow the style conventions of the surrounding code. In most cases, this is standard ruby style.
23
- 3) Add API documentation if it's a new feature
24
- 4) Update API documentation if it changes an existing feature
25
- 5) Bonus points for sending a PR to [github.com/dry-rb/dry-rb.org](github.com/dry-rb/dry-rb.org) which updates user documentation and guides
26
-
27
- # Asking for help
28
-
29
- If these guidelines aren't helpful, and you're stuck, please post a message on [discuss.dry-rb.org](https://discuss.dry-rb.org).