memoized 1.0.0 → 1.1.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 +4 -4
- data/.github/workflows/test.yml +38 -0
- data/.gitignore +3 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +60 -0
- data/Gemfile +9 -1
- data/Gemfile.lock +4 -2
- data/README.md +60 -4
- data/Rakefile +8 -0
- data/lib/memoized/version.rb +1 -1
- data/lib/memoized.rb +26 -9
- data/memoized.gemspec +7 -1
- data/spec/memoized_spec.rb +42 -0
- metadata +11 -7
- data/.travis.yml +0 -26
- data/CHANGELOG.txt +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b5c64274f2f14822e1da8bd04450fcaba727b7dd7310ab704e6d418651df057
|
4
|
+
data.tar.gz: f9afb8a81796f1841a5504eabeeb7a67956fc8c1b14e8e82cf89676c59449378
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39b17f38a9ffa32e4d3369e1d2e0f2d5db75e522bc412a63d984e0fffa0c3e17310e6dd7a50094c6554fea1192de13a5b5b290823f26a5ee5af62bc94e2e8911
|
7
|
+
data.tar.gz: 0e8696b57c1dee349ef43b40b1949af22ec3f826dbbf1d0fe8b39ddd7a751ba5ca5b0893335620cb21ef9e1fabf1f9e094c61524b97cd3a3ef0c14f26f3b455b
|
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
name: Tests
|
3
|
+
'on':
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- master
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- master
|
10
|
+
jobs:
|
11
|
+
test:
|
12
|
+
runs-on: ubuntu-20.04
|
13
|
+
strategy:
|
14
|
+
fail-fast: false
|
15
|
+
matrix:
|
16
|
+
include:
|
17
|
+
- ruby: 2.5.3
|
18
|
+
gemfile: Gemfile
|
19
|
+
- ruby: 2.6.7
|
20
|
+
gemfile: Gemfile
|
21
|
+
- ruby: 2.7.3
|
22
|
+
gemfile: Gemfile
|
23
|
+
- ruby: 3.0.1
|
24
|
+
gemfile: Gemfile
|
25
|
+
env:
|
26
|
+
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
27
|
+
steps:
|
28
|
+
- uses: actions/checkout@v2
|
29
|
+
- name: Install ruby
|
30
|
+
uses: ruby/setup-ruby@v1
|
31
|
+
with:
|
32
|
+
ruby-version: "${{ matrix.ruby }}"
|
33
|
+
- name: Bundle
|
34
|
+
run: |
|
35
|
+
gem install bundler:2.2.21
|
36
|
+
bundle install --no-deployment
|
37
|
+
- name: Run tests
|
38
|
+
run: bundle exec rspec
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.6.
|
1
|
+
2.6.7
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
All notable changes to this project will be documented in this file.
|
2
|
+
|
3
|
+
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
4
|
+
|
5
|
+
|
6
|
+
## Unreleased
|
7
|
+
|
8
|
+
### Breaking changes
|
9
|
+
|
10
|
+
-
|
11
|
+
|
12
|
+
### Compatible changes
|
13
|
+
|
14
|
+
-
|
15
|
+
|
16
|
+
## 1.1.0 - 2022-03-16
|
17
|
+
|
18
|
+
### Breaking changes
|
19
|
+
|
20
|
+
- Remove no longer supported ruby versions (2.3.8, 2.4.5)
|
21
|
+
|
22
|
+
### Compatible changes
|
23
|
+
|
24
|
+
- Activate rubygems MFA
|
25
|
+
|
26
|
+
## 1.0.2 - 2019-05-22
|
27
|
+
|
28
|
+
### Compatible changes
|
29
|
+
|
30
|
+
- Preserve arity of methods with optional arguments
|
31
|
+
|
32
|
+
## 1.0.1 - 2019-02-27
|
33
|
+
|
34
|
+
### Compatible changes
|
35
|
+
|
36
|
+
- Fix meta information in gemspec.
|
37
|
+
|
38
|
+
|
39
|
+
## 1.0.0 - 2019-02-27
|
40
|
+
|
41
|
+
### Compatible changes
|
42
|
+
|
43
|
+
Forked [memoizer](https://github.com/wegowise/memoizer) with two changes:
|
44
|
+
|
45
|
+
1. Memoized methods now preserve their [arity](https://apidock.com/ruby/Method/arity). Previously all memoized methods had an arity of `-1`.
|
46
|
+
2. Memoized methods are now faster at runtime. This will only be noticable if you call a memoized methods many times in the same request.
|
47
|
+
|
48
|
+
We published our fork as a new gem named [memoized](https://rubygems.org/gems/memoized).
|
49
|
+
|
50
|
+
memoized is API-compatible to memoizer, you just need to `include Memoized` instead of `Memoizer`:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
class A
|
54
|
+
include Memoized
|
55
|
+
|
56
|
+
memoize def hello
|
57
|
+
'hello!'
|
58
|
+
end
|
59
|
+
end
|
60
|
+
```
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
memoized (1.0
|
4
|
+
memoized (1.1.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
diff-lcs (1.3)
|
10
|
+
gemika (0.7.1)
|
10
11
|
rake (10.4.2)
|
11
12
|
rspec (3.5.0)
|
12
13
|
rspec-core (~> 3.5.0)
|
@@ -27,10 +28,11 @@ PLATFORMS
|
|
27
28
|
ruby
|
28
29
|
|
29
30
|
DEPENDENCIES
|
31
|
+
gemika
|
30
32
|
memoized!
|
31
33
|
rake (~> 10.4.2)
|
32
34
|
rspec (~> 3.5.0)
|
33
35
|
timecop (~> 0.8.0)
|
34
36
|
|
35
37
|
BUNDLED WITH
|
36
|
-
|
38
|
+
2.2.21
|
data/README.md
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
[](https://github.com/makandra/memoized/actions)
|
4
2
|
|
5
3
|
Memoized will memoize the results of your methods. It acts much like
|
6
4
|
`ActiveSupport::Memoizable` without all of that freezing business. The API for
|
@@ -14,7 +12,7 @@ $ gem install memoized
|
|
14
12
|
|
15
13
|
## Usage
|
16
14
|
|
17
|
-
To define a memoized instance method, use `
|
15
|
+
To define a memoized instance method, use `memoize def`:
|
18
16
|
|
19
17
|
```ruby
|
20
18
|
class A
|
@@ -78,6 +76,64 @@ instance.goodbye # the goodbye method is now memoized
|
|
78
76
|
instance.unmemoize_all # neither hello nor goodbye are memoized anymore
|
79
77
|
```
|
80
78
|
|
79
|
+
## Limitations
|
80
|
+
|
81
|
+
When you are using Memoized with default arguments or default keyword arguments, there are some edge cased you have to
|
82
|
+
keep in mind.
|
83
|
+
|
84
|
+
When you memoize a method with (keyword) arguments that have an expression as default value, you should be aware
|
85
|
+
that the expression is evaluated only once.
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
memoize def print_time(time = Time.now)
|
89
|
+
time
|
90
|
+
end
|
91
|
+
|
92
|
+
print_time
|
93
|
+
=> 2021-07-23 14:23:18 +0200
|
94
|
+
|
95
|
+
sleep(1.minute)
|
96
|
+
print_time
|
97
|
+
=> 2021-07-23 14:23:18 +0200
|
98
|
+
```
|
99
|
+
|
100
|
+
When you memoize a method with (keyword) arguments that have default values, you should be aware that Memoized
|
101
|
+
differentiates between a method call without arguments and the default values.
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
def true_or_false(default = true)
|
105
|
+
puts 'calculate value ...'
|
106
|
+
default
|
107
|
+
end
|
108
|
+
|
109
|
+
true_or_false
|
110
|
+
calculate value ...
|
111
|
+
=> true
|
112
|
+
|
113
|
+
true_or_false
|
114
|
+
=> true
|
115
|
+
|
116
|
+
true_or_false(true)
|
117
|
+
calculate value ...
|
118
|
+
=> true
|
119
|
+
```
|
120
|
+
|
121
|
+
## Development
|
122
|
+
|
123
|
+
There are tests in `spec`. We only accept PRs with tests. To run tests:
|
124
|
+
|
125
|
+
- Install Ruby 2.6.1
|
126
|
+
- Install development dependencies using `bundle install`
|
127
|
+
- Run tests using `bundle exec rake current_rspec`
|
128
|
+
|
129
|
+
We recommend to test large changes against multiple versions of Ruby. Supported combinations are configured in `.github/workflows/test.yml`. We provide some rake tasks to help with this:
|
130
|
+
|
131
|
+
- Install development dependencies using `bundle exec rake matrix:install`
|
132
|
+
- Run tests using `bundle exec rake matrix:spec`
|
133
|
+
|
134
|
+
Note that we have configured GitHub Actions to automatically run tests in all supported Ruby versions and dependency sets after each push. We will only merge pull requests after a green GitHub Actions run.
|
135
|
+
|
136
|
+
I'm very eager to keep this gem leightweight and on topic. If you're unsure whether a change would make it into the gem, [talk to me beforehand](mailto:henning.koch@makandra.de).
|
81
137
|
|
82
138
|
## License
|
83
139
|
|
data/Rakefile
CHANGED
data/lib/memoized/version.rb
CHANGED
data/lib/memoized.rb
CHANGED
@@ -22,8 +22,7 @@ module Memoized
|
|
22
22
|
|
23
23
|
arity = instance_method(unmemoized_method).arity
|
24
24
|
|
25
|
-
|
26
|
-
when 0
|
25
|
+
if arity == 0
|
27
26
|
module_eval(<<-RUBY)
|
28
27
|
def #{method_name}()
|
29
28
|
#{memoized_ivar_name} ||= [#{unmemoized_method}()]
|
@@ -31,7 +30,7 @@ module Memoized
|
|
31
30
|
end
|
32
31
|
RUBY
|
33
32
|
|
34
|
-
|
33
|
+
elsif arity == -1
|
35
34
|
module_eval(<<-RUBY)
|
36
35
|
def #{method_name}(*args)
|
37
36
|
#{memoized_ivar_name} ||= {}
|
@@ -43,18 +42,36 @@ module Memoized
|
|
43
42
|
end
|
44
43
|
RUBY
|
45
44
|
|
46
|
-
|
47
|
-
|
45
|
+
elsif arity < -1
|
46
|
+
# For Ruby methods that take a variable number of arguments,
|
47
|
+
# Method#arity returns -n-1, where n is the number of required arguments
|
48
|
+
required_arg_names = (1..(-arity - 1)).map { |i| "arg#{i}" }
|
49
|
+
required_args_ruby = required_arg_names.join(', ')
|
50
|
+
|
51
|
+
module_eval(<<-RUBY)
|
52
|
+
def #{method_name}(#{required_args_ruby}, *optional_args)
|
53
|
+
all_args = [#{required_args_ruby}, *optional_args]
|
54
|
+
#{memoized_ivar_name} ||= {}
|
55
|
+
if #{memoized_ivar_name}.has_key?(all_args)
|
56
|
+
#{memoized_ivar_name}[all_args]
|
57
|
+
else
|
58
|
+
#{memoized_ivar_name}[all_args] = #{unmemoized_method}(*all_args)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
RUBY
|
62
|
+
|
63
|
+
else # positive arity
|
64
|
+
arg_names = (1..arity).map { |i| "arg#{i}" }
|
48
65
|
args_ruby = arg_names.join(', ')
|
49
66
|
|
50
67
|
module_eval(<<-RUBY)
|
51
68
|
def #{method_name}(#{args_ruby})
|
52
|
-
|
69
|
+
all_args = [#{args_ruby}]
|
53
70
|
#{memoized_ivar_name} ||= {}
|
54
|
-
if #{memoized_ivar_name}.has_key?(
|
55
|
-
#{memoized_ivar_name}[
|
71
|
+
if #{memoized_ivar_name}.has_key?(all_args)
|
72
|
+
#{memoized_ivar_name}[all_args]
|
56
73
|
else
|
57
|
-
#{memoized_ivar_name}[
|
74
|
+
#{memoized_ivar_name}[all_args] = #{unmemoized_method}(#{args_ruby})
|
58
75
|
end
|
59
76
|
end
|
60
77
|
RUBY
|
data/memoized.gemspec
CHANGED
@@ -5,9 +5,15 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.name = "memoized"
|
6
6
|
s.version = Memoized::VERSION
|
7
7
|
s.authors = ["Barun Singh", "Henning Koch"]
|
8
|
-
s.homepage = "https://github.com/makandra/
|
8
|
+
s.homepage = "https://github.com/makandra/memoized"
|
9
9
|
s.summary = "Memoized caches the results of your method calls"
|
10
10
|
s.description = s.summary
|
11
|
+
s.metadata = {
|
12
|
+
'source_code_uri' => s.homepage,
|
13
|
+
'bug_tracker_uri' => 'https://github.com/makandra/memoized/issues',
|
14
|
+
'changelog_uri' => 'https://github.com/makandra/memoized/blob/master/CHANGELOG.md',
|
15
|
+
'rubygems_mfa_required' => 'true',
|
16
|
+
}
|
11
17
|
|
12
18
|
s.files = `git ls-files`.split("\n").reject { |path| File.lstat(path).symlink? }
|
13
19
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n").reject { |path| File.lstat(path).symlink? }
|
data/spec/memoized_spec.rb
CHANGED
@@ -145,6 +145,48 @@ describe Memoized do
|
|
145
145
|
|
146
146
|
end
|
147
147
|
|
148
|
+
context 'for methods with a required and an optional arg' do
|
149
|
+
|
150
|
+
class ArityRequiredAndOptional < MemoizedSpecClass
|
151
|
+
def foo(a, b = 'default')
|
152
|
+
return [a, b]
|
153
|
+
end
|
154
|
+
|
155
|
+
memoize :foo
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'creates a memoized method with a arity of -2' do
|
159
|
+
expect(ArityRequiredAndOptional.instance_method(:foo).arity).to eq(-2)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "preserves the optional arg's default value" do
|
163
|
+
instance = ArityRequiredAndOptional.new
|
164
|
+
expect(instance.foo('foo')).to eq ['foo', 'default']
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'for methods with a required arg and splat args' do
|
170
|
+
|
171
|
+
class ArityArgAndOptional < MemoizedSpecClass
|
172
|
+
def foo(a, *args)
|
173
|
+
return [a, args]
|
174
|
+
end
|
175
|
+
|
176
|
+
memoize :foo
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'creates a memoized method with a arity of -2' do
|
180
|
+
expect(ArityArgAndOptional.instance_method(:foo).arity).to eq(-2)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "passes the splat args to the memoized method" do
|
184
|
+
instance = ArityArgAndOptional.new
|
185
|
+
expect(instance.foo('foo', 'bar', 'baz')).to eq ['foo', ['bar', 'baz']]
|
186
|
+
end
|
187
|
+
|
188
|
+
end
|
189
|
+
|
148
190
|
end
|
149
191
|
|
150
192
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memoized
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Barun Singh
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-03-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -59,11 +59,11 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
+
- ".github/workflows/test.yml"
|
62
63
|
- ".gitignore"
|
63
64
|
- ".rspec"
|
64
65
|
- ".ruby-version"
|
65
|
-
-
|
66
|
-
- CHANGELOG.txt
|
66
|
+
- CHANGELOG.md
|
67
67
|
- Gemfile
|
68
68
|
- Gemfile.lock
|
69
69
|
- LICENSE.txt
|
@@ -74,10 +74,14 @@ files:
|
|
74
74
|
- memoized.gemspec
|
75
75
|
- spec/memoized_spec.rb
|
76
76
|
- spec/spec_helper.rb
|
77
|
-
homepage: https://github.com/makandra/
|
77
|
+
homepage: https://github.com/makandra/memoized
|
78
78
|
licenses:
|
79
79
|
- MIT
|
80
|
-
metadata:
|
80
|
+
metadata:
|
81
|
+
source_code_uri: https://github.com/makandra/memoized
|
82
|
+
bug_tracker_uri: https://github.com/makandra/memoized/issues
|
83
|
+
changelog_uri: https://github.com/makandra/memoized/blob/master/CHANGELOG.md
|
84
|
+
rubygems_mfa_required: 'true'
|
81
85
|
post_install_message:
|
82
86
|
rdoc_options: []
|
83
87
|
require_paths:
|
@@ -93,7 +97,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
93
97
|
- !ruby/object:Gem::Version
|
94
98
|
version: '0'
|
95
99
|
requirements: []
|
96
|
-
rubygems_version: 3.
|
100
|
+
rubygems_version: 3.2.21
|
97
101
|
signing_key:
|
98
102
|
specification_version: 4
|
99
103
|
summary: Memoized caches the results of your method calls
|
data/.travis.yml
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
rvm:
|
4
|
-
- 2.1.8
|
5
|
-
- 2.3.8
|
6
|
-
- 2.4.5
|
7
|
-
- 2.5.3
|
8
|
-
- 2.6.1
|
9
|
-
|
10
|
-
gemfile:
|
11
|
-
- Gemfile
|
12
|
-
|
13
|
-
script: bundle exec rspec spec
|
14
|
-
|
15
|
-
sudo: false
|
16
|
-
|
17
|
-
cache: bundler
|
18
|
-
|
19
|
-
notifications:
|
20
|
-
email:
|
21
|
-
- fail@makandra.de
|
22
|
-
|
23
|
-
install:
|
24
|
-
# Replace default Travis CI bundler script with a version that doesn't
|
25
|
-
# explode when lockfile doesn't match recently bumped version
|
26
|
-
- bundle install --no-deployment --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
|
data/CHANGELOG.txt
DELETED