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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30eefb403ce7300b9b943f9a6a946c56ac21fe619323ace0c06e63ca11198eab
4
- data.tar.gz: 5e0e371e3bb72db04dec7fd23789a4c88f1acfffcf49c898529c5edcd60594a4
3
+ metadata.gz: 1b5c64274f2f14822e1da8bd04450fcaba727b7dd7310ab704e6d418651df057
4
+ data.tar.gz: f9afb8a81796f1841a5504eabeeb7a67956fc8c1b14e8e82cf89676c59449378
5
5
  SHA512:
6
- metadata.gz: 7402174132f312c8e7f45389fd18fcae350aeffc006587c0d20921b4ead346ef794c90634e4c6c367891050edbc6d5c0982a4203e822dc9c3cda9b91dfd9ee76
7
- data.tar.gz: 6a0676fcac1c743821fde6b3010d9d53a0792097775593fb41a7c912ca45ddb2ef68276cae9996aa96cc7ee92274c1c62e0e0af2442b02d4d69858442f90e99c
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
@@ -1 +1,3 @@
1
- .idea
1
+ /.idea
2
+ /pkg
3
+
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.1
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
@@ -1,2 +1,10 @@
1
1
  source 'https://rubygems.org'
2
- gemspec
2
+
3
+ # Development dependencies
4
+ gem 'rake', '~> 10.4.2'
5
+ gem 'rspec', '~> 3.5.0'
6
+ gem 'timecop', '~> 0.8.0'
7
+ gem 'gemika'
8
+
9
+ # Gem under test
10
+ gem 'memoized', :path => '.'
data/Gemfile.lock CHANGED
@@ -1,12 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- memoized (1.0.3)
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
- 1.17.2
38
+ 2.2.21
data/README.md CHANGED
@@ -1,6 +1,4 @@
1
- [![Build Status](https://travis-ci.org/makandra/memoized.svg?branch=master)](https://travis-ci.org/makandra/memoized)
2
-
3
- # Memoized
1
+ # Memoized [![Tests](https://github.com/makandra/memoized/workflows/Tests/badge.svg)](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 `memoized def``:
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
@@ -1,2 +1,10 @@
1
1
  require 'rake'
2
2
  require 'bundler/gem_tasks'
3
+
4
+ begin
5
+ require 'gemika/tasks'
6
+ rescue LoadError
7
+ puts 'Run `gem install gemika` for additional tasks'
8
+ end
9
+
10
+ task :default => 'matrix:spec'
@@ -1,3 +1,3 @@
1
1
  module Memoized
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
data/lib/memoized.rb CHANGED
@@ -22,8 +22,7 @@ module Memoized
22
22
 
23
23
  arity = instance_method(unmemoized_method).arity
24
24
 
25
- case arity
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
- when -1
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
- else
47
- arg_names = (0..(arity - 1)).map { |i| "arg#{i}" }
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
- args = [#{args_ruby}]
69
+ all_args = [#{args_ruby}]
53
70
  #{memoized_ivar_name} ||= {}
54
- if #{memoized_ivar_name}.has_key?(args)
55
- #{memoized_ivar_name}[args]
71
+ if #{memoized_ivar_name}.has_key?(all_args)
72
+ #{memoized_ivar_name}[all_args]
56
73
  else
57
- #{memoized_ivar_name}[args] = #{unmemoized_method}(#{args_ruby})
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/memoizer"
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? }
@@ -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.0.0
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: 2019-02-27 00:00:00.000000000 Z
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
- - ".travis.yml"
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/memoizer
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.0.1
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
@@ -1,4 +0,0 @@
1
- == 1.0.1
2
- * Bump version to avoid conflict with old memoizer gem
3
- == 1.0.0
4
- * Initial release