dry-core 0.4.8 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
3
+ require "set"
4
4
 
5
5
  module Dry
6
6
  module Core
@@ -7,15 +7,15 @@ module Dry
7
7
  # List of supported backends
8
8
  BACKENDS = {
9
9
  activesupport: [
10
- 'active_support/inflector',
10
+ "active_support/inflector",
11
11
  proc { ::ActiveSupport::Inflector }
12
12
  ],
13
13
  dry_inflector: [
14
- 'dry/inflector',
14
+ "dry/inflector",
15
15
  proc { Dry::Inflector.new }
16
16
  ],
17
17
  inflecto: [
18
- 'inflecto',
18
+ "inflecto",
19
19
  proc { ::Inflecto }
20
20
  ]
21
21
  }.freeze
@@ -49,6 +49,7 @@ module Dry
49
49
  if name && !BACKENDS.key?(name)
50
50
  raise NameError, "Invalid inflector library selection: '#{name}'"
51
51
  end
52
+
52
53
  @inflector = name ? realize_backend(*BACKENDS[name]) : detect_backend
53
54
  end
54
55
 
@@ -1,69 +1,181 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "dry/core/deprecations"
4
+
3
5
  module Dry
4
6
  module Core
5
7
  module Memoizable
6
8
  MEMOIZED_HASH = {}.freeze
7
9
 
8
10
  module ClassInterface
9
- def memoize(*names)
10
- prepend(Memoizer.new(self, names))
11
+ module Base
12
+ def memoize(*names)
13
+ prepend(Memoizer.new(self, names))
14
+ end
11
15
  end
12
16
 
13
- def new(*)
14
- obj = super
15
- obj.instance_variable_set(:'@__memoized__', MEMOIZED_HASH.dup)
16
- obj
17
+ module BasicObject
18
+ include Base
19
+
20
+ def new(*)
21
+ obj = super
22
+ obj.instance_eval { @__memoized__ = MEMOIZED_HASH.dup }
23
+ obj
24
+ end
25
+ end
26
+
27
+ module Object
28
+ include Base
29
+
30
+ def new(*)
31
+ obj = super
32
+ obj.instance_variable_set(:@__memoized__, MEMOIZED_HASH.dup)
33
+ obj
34
+ end
35
+
36
+ if respond_to?(:ruby2_keywords, true)
37
+ ruby2_keywords(:new)
38
+ end
17
39
  end
18
40
  end
19
41
 
20
42
  def self.included(klass)
21
43
  super
22
- klass.extend(ClassInterface)
23
- end
24
44
 
25
- attr_reader :__memoized__
45
+ if klass <= Object
46
+ klass.extend(ClassInterface::Object)
47
+ else
48
+ klass.extend(ClassInterface::BasicObject)
49
+ end
50
+ end
26
51
 
27
52
  # @api private
28
- class Memoizer < Module
29
- attr_reader :klass
30
- attr_reader :names
31
-
53
+ class Memoizer < ::Module
32
54
  # @api private
33
55
  def initialize(klass, names)
34
- @names = names
35
- @klass = klass
36
- define_memoizable_names!
56
+ super()
57
+ names.each do |name|
58
+ define_memoizable(
59
+ method: klass.instance_method(name)
60
+ )
61
+ end
37
62
  end
38
63
 
39
64
  private
40
65
 
41
66
  # @api private
42
- def define_memoizable_names!
43
- names.each do |name|
44
- meth = klass.instance_method(name)
45
-
46
- if meth.parameters.size > 0
47
- define_method(name) do |*args|
48
- name_with_args = :"#{name}_#{args.hash}"
67
+ def define_memoizable(method:)
68
+ parameters = method.parameters
49
69
 
50
- if __memoized__.key?(name_with_args)
51
- __memoized__[name_with_args]
70
+ if parameters.empty?
71
+ key = method.name.hash
72
+ module_eval <<~RUBY, __FILE__, __LINE__ + 1
73
+ def #{method.name}
74
+ if @__memoized__.key?(#{key})
75
+ @__memoized__[#{key}]
52
76
  else
53
- __memoized__[name_with_args] = super(*args)
77
+ @__memoized__[#{key}] = super
54
78
  end
55
79
  end
56
- else
57
- define_method(name) do
58
- if __memoized__.key?(name)
59
- __memoized__[name]
80
+ RUBY
81
+ else
82
+ mapping = parameters.to_h { |k, v = nil| [k, v] }
83
+ params, binds = declaration(parameters, mapping)
84
+
85
+ if parameters.last[0].eql?(:block)
86
+ Deprecations.warn(<<~WARN)
87
+ Memoization for block-accepting methods isn't safe.
88
+ Every call creates a new block instance bloating cached results.
89
+ In the future, blocks will still be allowed but won't participate in
90
+ cache key calculation.
91
+ WARN
92
+ end
93
+
94
+ module_eval <<~RUBY, __FILE__, __LINE__ + 1
95
+ def #{method.name}(#{params.join(", ")})
96
+ key = [:"#{method.name}", #{binds.join(", ")}].hash
97
+
98
+ if @__memoized__.key?(key)
99
+ @__memoized__[key]
60
100
  else
61
- __memoized__[name] = super()
101
+ @__memoized__[key] = super
62
102
  end
63
103
  end
104
+ RUBY
105
+
106
+ if respond_to?(:ruby2_keywords, true) && mapping.key?(:reyrest)
107
+ ruby2_keywords(method.name)
64
108
  end
65
109
  end
66
110
  end
111
+
112
+ # @api private
113
+ def declaration(definition, lookup)
114
+ params = []
115
+ binds = []
116
+ defined = {}
117
+
118
+ definition.each do |type, name|
119
+ mapped_type = map_bind_type(type, lookup, defined) do
120
+ raise ::NotImplementedError, "type: #{type}, name: #{name}"
121
+ end
122
+
123
+ if mapped_type
124
+ defined[mapped_type] = true
125
+ bind = name || make_bind_name(binds.size)
126
+
127
+ binds << bind
128
+ params << param(bind, mapped_type)
129
+ end
130
+ end
131
+
132
+ [params, binds]
133
+ end
134
+
135
+ # @api private
136
+ def make_bind_name(idx)
137
+ :"__lv_#{idx}__"
138
+ end
139
+
140
+ # @api private
141
+ def map_bind_type(type, original_params, defined_types) # rubocop:disable Metrics/PerceivedComplexity
142
+ case type
143
+ when :req
144
+ :reqular
145
+ when :rest, :keyreq, :keyrest, :block
146
+ type
147
+ when :opt
148
+ if original_params.key?(:rest) || defined_types[:rest]
149
+ nil
150
+ else
151
+ :rest
152
+ end
153
+ when :key
154
+ if original_params.key?(:keyrest) || defined_types[:keyrest]
155
+ nil
156
+ else
157
+ :keyrest
158
+ end
159
+ else
160
+ yield
161
+ end
162
+ end
163
+
164
+ # @api private
165
+ def param(name, type)
166
+ case type
167
+ when :reqular
168
+ name
169
+ when :rest
170
+ "*#{name}"
171
+ when :keyreq
172
+ "#{name}:"
173
+ when :keyrest
174
+ "**#{name}"
175
+ when :block
176
+ "&#{name}"
177
+ end
178
+ end
67
179
  end
68
180
  end
69
181
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Dry
4
4
  module Core
5
- VERSION = '0.4.8'.freeze
5
+ VERSION = "0.7.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.8
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nikita Shilnikov
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2019-06-23 00:00:00.000000000 Z
11
+ date: 2021-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -42,48 +42,40 @@ dependencies:
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '3.0'
61
+ version: '0'
62
62
  type: :development
63
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.0'
69
- description: A toolset of small support modules used throughout the dry-rb ecosystem.
68
+ version: '0'
69
+ description: A toolset of small support modules used throughout the dry-rb ecosystem
70
70
  email:
71
71
  - fg@flashgordon.ru
72
72
  executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
- - ".codeclimate.yml"
77
- - ".gitignore"
78
- - ".inch.yml"
79
- - ".rspec"
80
- - ".travis.yml"
81
76
  - CHANGELOG.md
82
- - CONTRIBUTING.md
83
- - Gemfile
84
- - LICENSE.txt
77
+ - LICENSE
85
78
  - README.md
86
- - Rakefile
87
79
  - dry-core.gemspec
88
80
  - lib/dry-core.rb
89
81
  - lib/dry/core.rb
@@ -93,16 +85,20 @@ files:
93
85
  - lib/dry/core/constants.rb
94
86
  - lib/dry/core/deprecations.rb
95
87
  - lib/dry/core/descendants_tracker.rb
88
+ - lib/dry/core/equalizer.rb
96
89
  - lib/dry/core/errors.rb
97
90
  - lib/dry/core/extensions.rb
98
91
  - lib/dry/core/inflector.rb
99
92
  - lib/dry/core/memoizable.rb
100
93
  - lib/dry/core/version.rb
101
- homepage: https://github.com/dry-rb/dry-core
94
+ homepage: https://dry-rb.org/gems/dry-core
102
95
  licenses:
103
96
  - MIT
104
97
  metadata:
105
98
  allowed_push_host: https://rubygems.org
99
+ changelog_uri: https://github.com/dry-rb/dry-core/blob/master/CHANGELOG.md
100
+ source_code_uri: https://github.com/dry-rb/dry-core
101
+ bug_tracker_uri: https://github.com/dry-rb/dry-core/issues
106
102
  post_install_message:
107
103
  rdoc_options: []
108
104
  require_paths:
@@ -111,15 +107,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
111
107
  requirements:
112
108
  - - ">="
113
109
  - !ruby/object:Gem::Version
114
- version: 2.1.0
110
+ version: 2.6.0
115
111
  required_rubygems_version: !ruby/object:Gem::Requirement
116
112
  requirements:
117
113
  - - ">="
118
114
  - !ruby/object:Gem::Version
119
115
  version: '0'
120
116
  requirements: []
121
- rubygems_version: 3.0.3
117
+ rubygems_version: 3.1.6
122
118
  signing_key:
123
119
  specification_version: 4
124
- summary: A toolset of small support modules used throughout the dry-rb ecosystem.
120
+ summary: A toolset of small support modules used throughout the dry-rb ecosystem
125
121
  test_files: []
data/.codeclimate.yml DELETED
@@ -1,15 +0,0 @@
1
- version: "2"
2
-
3
- prepare:
4
- fetch:
5
- - url: "https://raw.githubusercontent.com/dry-rb/devtools/master/.rubocop.yml"
6
- path: ".rubocop.yml"
7
-
8
- exclude_patterns:
9
- - "benchmarks/"
10
- - "examples/"
11
- - "spec/"
12
-
13
- plugins:
14
- rubocop:
15
- enabled: true
data/.gitignore DELETED
@@ -1,11 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- spec/examples.txt
11
- .rubocop.yml
data/.inch.yml DELETED
@@ -1,4 +0,0 @@
1
- files:
2
- excluded:
3
- - lib/dry/core.rb
4
- - lib/dry/core/version.rb
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format progress
2
- --color
3
- --require ./spec/spec_helper.rb
data/.travis.yml DELETED
@@ -1,32 +0,0 @@
1
- language: ruby
2
- dist: trusty
3
- sudo: required
4
- cache: bundler
5
- bundler_args: --without benchmarks tools
6
- after_success:
7
- - '[ -d coverage ] && bundle exec codeclimate-test-reporter'
8
- before_install:
9
- - gem install bundler
10
- after_success:
11
- - '[ -d coverage ] && bundle exec codeclimate-test-reporter'
12
- rvm:
13
- - 2.4.6
14
- - 2.5.5
15
- - 2.6.3
16
- - jruby-9.2.7.0
17
- - truffleruby
18
- env:
19
- global:
20
- - COVERAGE=true
21
- - JRUBY_OPTS='--dev -J-Xmx1024M'
22
- matrix:
23
- allow_failures:
24
- - rvm: truffleruby
25
- notifications:
26
- email: false
27
- webhooks:
28
- urls:
29
- - https://webhooks.gitter.im/e/19098b4253a72c9796db
30
- on_success: change # options: [always|never|change] default: always
31
- on_failure: always # options: [always|never|change] default: always
32
- on_start: false # default: false