dry-core 0.7.1 → 1.0.1
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 +4 -4
- data/CHANGELOG.md +69 -1
- data/LICENSE +1 -1
- data/README.md +4 -12
- data/dry-core.gemspec +3 -2
- data/lib/dry/core/basic_object.rb +144 -0
- data/lib/dry/core/cache.rb +2 -2
- data/lib/dry/core/class_attributes.rb +2 -4
- data/lib/dry/core/constants.rb +1 -1
- data/lib/dry/core/container/config.rb +34 -0
- data/lib/dry/core/container/configuration.rb +37 -0
- data/lib/dry/core/container/item/callable.rb +22 -0
- data/lib/dry/core/container/item/factory.rb +29 -0
- data/lib/dry/core/container/item/memoizable.rb +49 -0
- data/lib/dry/core/container/item.rb +53 -0
- data/lib/dry/core/container/mixin.rb +311 -0
- data/lib/dry/core/container/namespace.rb +47 -0
- data/lib/dry/core/container/namespace_dsl.rb +63 -0
- data/lib/dry/core/container/registry.rb +52 -0
- data/lib/dry/core/container/resolver.rb +90 -0
- data/lib/dry/core/container/stub.rb +57 -0
- data/lib/dry/core/container.rb +27 -0
- data/lib/dry/core/deprecations.rb +1 -1
- data/lib/dry/core/equalizer.rb +15 -11
- data/lib/dry/core/errors.rb +1 -1
- data/lib/dry/core/memoizable.rb +57 -14
- data/lib/dry/core/version.rb +1 -1
- data/lib/dry/core.rb +46 -0
- metadata +33 -5
data/lib/dry/core/memoizable.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "dry/core/deprecations"
|
4
|
-
|
5
3
|
module Dry
|
6
4
|
module Core
|
7
5
|
module Memoizable
|
@@ -13,6 +11,13 @@ module Dry
|
|
13
11
|
def memoize(*names)
|
14
12
|
prepend(Memoizer.new(self, names))
|
15
13
|
end
|
14
|
+
|
15
|
+
def inherited(base)
|
16
|
+
super
|
17
|
+
|
18
|
+
memoizer = base.ancestors.find { _1.is_a?(Memoizer) }
|
19
|
+
base.prepend(memoizer.dup) if memoizer
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
23
|
module BasicObject
|
@@ -52,6 +57,12 @@ module Dry
|
|
52
57
|
|
53
58
|
# @api private
|
54
59
|
class Memoizer < ::Module
|
60
|
+
KERNEL = {
|
61
|
+
singleton: ::Kernel.instance_method(:singleton_class),
|
62
|
+
ivar_set: ::Kernel.instance_method(:instance_variable_set),
|
63
|
+
frozen: ::Kernel.instance_method(:frozen?)
|
64
|
+
}.freeze
|
65
|
+
|
55
66
|
# @api private
|
56
67
|
def initialize(klass, names)
|
57
68
|
super()
|
@@ -65,20 +76,50 @@ module Dry
|
|
65
76
|
private
|
66
77
|
|
67
78
|
# @api private
|
68
|
-
|
79
|
+
# rubocop:disable Metrics/AbcSize
|
80
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
81
|
+
def define_memoizable(method:)
|
69
82
|
parameters = method.parameters
|
83
|
+
mod = self
|
84
|
+
kernel = KERNEL
|
70
85
|
|
71
86
|
if parameters.empty?
|
72
|
-
key = method.name.hash
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
87
|
+
key = "#{object_id}:#{method.name}".hash.abs
|
88
|
+
|
89
|
+
define_method(method.name) do
|
90
|
+
value = super()
|
91
|
+
|
92
|
+
if kernel[:frozen].bind_call(self)
|
93
|
+
# It's not possible to modify singleton classes
|
94
|
+
# of frozen objects
|
95
|
+
mod.remove_method(method.name)
|
96
|
+
mod.module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
97
|
+
def #{method.name} # def slow_calc
|
98
|
+
cached = @__memoized__[#{key}] # cached = @__memoized__[12345678]
|
99
|
+
#
|
100
|
+
if cached || @__memoized__.key?(#{key}) # if cached || @__memoized__.key?(12345678)
|
101
|
+
cached # cached
|
102
|
+
else # else
|
103
|
+
@__memoized__[#{key}] = super # @__memoized__[12345678] = super
|
104
|
+
end # end
|
105
|
+
end # end
|
106
|
+
RUBY
|
107
|
+
else
|
108
|
+
# We make an attr_reader for computed value.
|
109
|
+
# Readers are "special-cased" in ruby so such
|
110
|
+
# access will be the fastest way, faster than you'd
|
111
|
+
# expect :)
|
112
|
+
attr_name = :"__memozed_#{key}__"
|
113
|
+
ivar_name = :"@#{attr_name}"
|
114
|
+
kernel[:ivar_set].bind_call(self, ivar_name, value)
|
115
|
+
eigenclass = kernel[:singleton].bind_call(self)
|
116
|
+
eigenclass.attr_reader(attr_name)
|
117
|
+
eigenclass.alias_method(method.name, attr_name)
|
118
|
+
eigenclass.remove_method(attr_name)
|
119
|
+
end
|
120
|
+
|
121
|
+
value
|
122
|
+
end
|
82
123
|
else
|
83
124
|
mapping = parameters.to_h { |k, v = nil| [k, v] }
|
84
125
|
params, binds = declaration(parameters, mapping)
|
@@ -95,7 +136,7 @@ module Dry
|
|
95
136
|
|
96
137
|
m = module_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
97
138
|
def #{method.name}(#{params.join(", ")}) # def slow_calc(arg1, arg2, arg3)
|
98
|
-
key = [:"#{method.name}", #{binds.join(", ")}].hash # [:slow_calc, arg1, arg2, arg3].hash
|
139
|
+
key = [:"#{method.name}", #{binds.join(", ")}].hash # key = [:slow_calc, arg1, arg2, arg3].hash
|
99
140
|
#
|
100
141
|
if @__memoized__.key?(key) # if @__memoized__.key?(key)
|
101
142
|
@__memoized__[key] # @__memoized__[key]
|
@@ -112,6 +153,8 @@ module Dry
|
|
112
153
|
m
|
113
154
|
end
|
114
155
|
end
|
156
|
+
# rubocop:enable Metrics/AbcSize
|
157
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
115
158
|
|
116
159
|
# @api private
|
117
160
|
def declaration(definition, lookup)
|
data/lib/dry/core/version.rb
CHANGED
data/lib/dry/core.rb
CHANGED
@@ -1,10 +1,56 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "zeitwerk"
|
4
|
+
|
5
|
+
require "dry/core/constants"
|
6
|
+
require "dry/core/errors"
|
3
7
|
require "dry/core/version"
|
4
8
|
|
5
9
|
# :nodoc:
|
6
10
|
module Dry
|
7
11
|
# :nodoc:
|
8
12
|
module Core
|
13
|
+
include Constants
|
14
|
+
|
15
|
+
def self.loader
|
16
|
+
@loader ||= Zeitwerk::Loader.new.tap do |loader|
|
17
|
+
root = File.expand_path("..", __dir__)
|
18
|
+
loader.tag = "dry-core"
|
19
|
+
loader.inflector = Zeitwerk::GemInflector.new("#{root}/dry-core.rb")
|
20
|
+
loader.push_dir(root)
|
21
|
+
loader.ignore(
|
22
|
+
"#{root}/dry-core.rb",
|
23
|
+
"#{root}/dry/core/{constants,errors,version}.rb"
|
24
|
+
)
|
25
|
+
loader.inflector.inflect("namespace_dsl" => "NamespaceDSL")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
loader.setup
|
30
|
+
|
31
|
+
# Build an equalizer module for the inclusion in other class
|
32
|
+
#
|
33
|
+
# ## Credits
|
34
|
+
#
|
35
|
+
# Equalizer has been originally imported from the equalizer gem created by Dan Kubb
|
36
|
+
#
|
37
|
+
# @api public
|
38
|
+
def self.Equalizer(*keys, **options)
|
39
|
+
Equalizer.new(*keys, **options)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# See dry/core/equalizer.rb
|
44
|
+
unless singleton_class.method_defined?(:Equalizer)
|
45
|
+
# Build an equalizer module for the inclusion in other class
|
46
|
+
#
|
47
|
+
# ## Credits
|
48
|
+
#
|
49
|
+
# Equalizer has been originally imported from the equalizer gem created by Dan Kubb
|
50
|
+
#
|
51
|
+
# @api public
|
52
|
+
def self.Equalizer(*keys, **options)
|
53
|
+
Dry::Core::Equalizer.new(*keys, **options)
|
54
|
+
end
|
9
55
|
end
|
10
56
|
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
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikita Shilnikov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: zeitwerk
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.6'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.6'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -79,10 +93,24 @@ files:
|
|
79
93
|
- dry-core.gemspec
|
80
94
|
- lib/dry-core.rb
|
81
95
|
- lib/dry/core.rb
|
96
|
+
- lib/dry/core/basic_object.rb
|
82
97
|
- lib/dry/core/cache.rb
|
83
98
|
- lib/dry/core/class_attributes.rb
|
84
99
|
- lib/dry/core/class_builder.rb
|
85
100
|
- lib/dry/core/constants.rb
|
101
|
+
- lib/dry/core/container.rb
|
102
|
+
- lib/dry/core/container/config.rb
|
103
|
+
- lib/dry/core/container/configuration.rb
|
104
|
+
- lib/dry/core/container/item.rb
|
105
|
+
- lib/dry/core/container/item/callable.rb
|
106
|
+
- lib/dry/core/container/item/factory.rb
|
107
|
+
- lib/dry/core/container/item/memoizable.rb
|
108
|
+
- lib/dry/core/container/mixin.rb
|
109
|
+
- lib/dry/core/container/namespace.rb
|
110
|
+
- lib/dry/core/container/namespace_dsl.rb
|
111
|
+
- lib/dry/core/container/registry.rb
|
112
|
+
- lib/dry/core/container/resolver.rb
|
113
|
+
- lib/dry/core/container/stub.rb
|
86
114
|
- lib/dry/core/deprecations.rb
|
87
115
|
- lib/dry/core/descendants_tracker.rb
|
88
116
|
- lib/dry/core/equalizer.rb
|
@@ -96,7 +124,7 @@ licenses:
|
|
96
124
|
- MIT
|
97
125
|
metadata:
|
98
126
|
allowed_push_host: https://rubygems.org
|
99
|
-
changelog_uri: https://github.com/dry-rb/dry-core/blob/
|
127
|
+
changelog_uri: https://github.com/dry-rb/dry-core/blob/main/CHANGELOG.md
|
100
128
|
source_code_uri: https://github.com/dry-rb/dry-core
|
101
129
|
bug_tracker_uri: https://github.com/dry-rb/dry-core/issues
|
102
130
|
post_install_message:
|
@@ -107,14 +135,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
107
135
|
requirements:
|
108
136
|
- - ">="
|
109
137
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
138
|
+
version: 3.0.0
|
111
139
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
140
|
requirements:
|
113
141
|
- - ">="
|
114
142
|
- !ruby/object:Gem::Version
|
115
143
|
version: '0'
|
116
144
|
requirements: []
|
117
|
-
rubygems_version: 3.
|
145
|
+
rubygems_version: 3.3.26
|
118
146
|
signing_key:
|
119
147
|
specification_version: 4
|
120
148
|
summary: A toolset of small support modules used throughout the dry-rb ecosystem
|