memoit 0.1.2 → 0.4.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 +5 -5
- data/.github/workflows/ci.yml +28 -0
- data/README.md +20 -1
- data/Rakefile +4 -0
- data/lib/memoit/version.rb +1 -1
- data/lib/memoit.rb +18 -9
- data/memoit.gemspec +3 -4
- data/spec/memoit_spec.rb +96 -0
- metadata +14 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 589b739844b381707d83e9dcd9c81008951e388c9fbb5361821f9d3ead7f9c60
|
4
|
+
data.tar.gz: 6c3e96182dea40b2693db9937f434cff394aaa1b71c88c28f375a53cd13874d7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 187ec3e55ed71647a49c0379c2cbf855b9ce94c266b3e7d1183d1deafcb568cc9305ba5d92d8256872fe998e02816f4f0a75e9a7ddc850d44c754e17c56c8609
|
7
|
+
data.tar.gz: f442100c27d3165c5388f75bb4d6e5c72a8c37c7a50151b5c593bfb5e82df77cb045a366a3e4d08d40b172898d277964ed8d3aaabef32a494bd50e80fb0cd18c
|
@@ -0,0 +1,28 @@
|
|
1
|
+
name: Ruby CI
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
pull_request:
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
test:
|
9
|
+
|
10
|
+
runs-on: ubuntu-latest
|
11
|
+
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
ruby-version:
|
15
|
+
- 3.1
|
16
|
+
- "3.0"
|
17
|
+
- 2.7
|
18
|
+
- jruby-9.3
|
19
|
+
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v3
|
22
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
23
|
+
uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby-version }}
|
26
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
27
|
+
- name: Run tests
|
28
|
+
run: bundle exec rake
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Memoit
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/memoit)
|
4
|
+
[](https://github.com/jnicklas/memoit/actions/workflows/ci.yml)
|
5
|
+
|
3
6
|
Memoizes methods.
|
4
7
|
|
5
8
|
## Installation
|
@@ -17,9 +20,25 @@ class Foo
|
|
17
20
|
memoize def bar(value)
|
18
21
|
expensive_calculation(value)
|
19
22
|
end
|
23
|
+
|
24
|
+
memoize_class_method def self.baz(value)
|
25
|
+
expensive_calculation(value)
|
26
|
+
end
|
20
27
|
end
|
21
28
|
```
|
22
29
|
|
30
|
+
## Is it any good?
|
31
|
+
|
32
|
+
[Yes](https://news.ycombinator.com/item?id=3067434).
|
33
|
+
|
34
|
+
## Development
|
35
|
+
|
36
|
+
```sh
|
37
|
+
gem install bundler
|
38
|
+
bundle install
|
39
|
+
rspec
|
40
|
+
```
|
41
|
+
|
23
42
|
## License
|
24
43
|
|
25
|
-
[MIT](
|
44
|
+
[MIT](LICENSE.txt)
|
data/Rakefile
CHANGED
data/lib/memoit/version.rb
CHANGED
data/lib/memoit.rb
CHANGED
@@ -11,20 +11,29 @@ module Memoit
|
|
11
11
|
# end
|
12
12
|
# end
|
13
13
|
def memoize(name)
|
14
|
-
|
14
|
+
ivar_method_name = name.to_s.sub("?", "__questionmark").sub("!", "__bang")
|
15
|
+
ivar_name = "@_memo_#{ivar_method_name}".to_sym
|
15
16
|
mod = Module.new do
|
16
|
-
define_method(name) do |*args, &block|
|
17
|
-
return super(*args, &block) if block
|
17
|
+
define_method(name) do |*args, **kwargs, &block|
|
18
|
+
return super(*args, **kwargs, &block) if block
|
18
19
|
cache = instance_variable_get(ivar_name) || instance_variable_set(ivar_name, {})
|
19
|
-
hash = args
|
20
|
-
if cache.has_key?(hash)
|
21
|
-
cache[hash]
|
22
|
-
else
|
23
|
-
cache[hash] = super(*args)
|
24
|
-
end
|
20
|
+
cache.fetch(args.hash) { |hash| cache[hash] = super(*args, **kwargs) }
|
25
21
|
end
|
26
22
|
end
|
27
23
|
prepend mod
|
24
|
+
name
|
25
|
+
end
|
26
|
+
|
27
|
+
# Memoize the class method with the given name.
|
28
|
+
#
|
29
|
+
# @example
|
30
|
+
# class Foo
|
31
|
+
# memoize_class_method def self.bar(value)
|
32
|
+
# expensive_calculation(value)
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
def memoize_class_method(name)
|
36
|
+
singleton_class.memoize(name)
|
28
37
|
end
|
29
38
|
end
|
30
39
|
|
data/memoit.gemspec
CHANGED
@@ -13,13 +13,12 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
16
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
17
|
spec.require_paths = ["lib"]
|
19
18
|
|
20
19
|
spec.required_ruby_version = ">= 2.1.0"
|
21
20
|
|
22
|
-
spec.add_development_dependency "bundler", "~>
|
23
|
-
spec.add_development_dependency "rake", "~>
|
24
|
-
spec.add_development_dependency "rspec", "~> 3.
|
21
|
+
spec.add_development_dependency "bundler", "~> 2.3"
|
22
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.10"
|
25
24
|
end
|
data/spec/memoit_spec.rb
CHANGED
@@ -3,6 +3,10 @@ require "memoit"
|
|
3
3
|
describe Memoit do
|
4
4
|
let(:klass) do
|
5
5
|
Class.new do
|
6
|
+
memoize_class_method def self.foo
|
7
|
+
rand
|
8
|
+
end
|
9
|
+
|
6
10
|
memoize def foo
|
7
11
|
rand
|
8
12
|
end
|
@@ -11,10 +15,38 @@ describe Memoit do
|
|
11
15
|
rand
|
12
16
|
end
|
13
17
|
|
18
|
+
memoize def baz(pos = nil, hash = {}, kwak: nil)
|
19
|
+
rand
|
20
|
+
end
|
21
|
+
|
22
|
+
memoize def qux(pos = nil, kwak: nil)
|
23
|
+
rand
|
24
|
+
end
|
25
|
+
|
26
|
+
memoize def quux(kwak: nil)
|
27
|
+
rand
|
28
|
+
end
|
29
|
+
|
30
|
+
memoize def corge(hash = {}, kwak: nil)
|
31
|
+
rand
|
32
|
+
end
|
33
|
+
|
14
34
|
memoize def falsy
|
15
35
|
foo
|
16
36
|
false
|
17
37
|
end
|
38
|
+
|
39
|
+
memoize def query?
|
40
|
+
rand
|
41
|
+
end
|
42
|
+
|
43
|
+
memoize def bang!
|
44
|
+
rand
|
45
|
+
end
|
46
|
+
|
47
|
+
memoize def ☃
|
48
|
+
rand
|
49
|
+
end
|
18
50
|
end
|
19
51
|
end
|
20
52
|
let(:instance) { klass.new }
|
@@ -33,6 +65,24 @@ describe Memoit do
|
|
33
65
|
expect(instance.bar(a, 1, :foo, "bar")).not_to eq(instance.bar(Object.new, 1, :foo, "bar"))
|
34
66
|
end
|
35
67
|
|
68
|
+
it "caches results when positional, hash and keyword arguments are used" do
|
69
|
+
a = Object.new
|
70
|
+
expect(instance.baz(a, { hash_key: "hash_value" }, kwak: "kwav")).to eq(instance.baz(a, { hash_key: "hash_value" }, kwak: "kwav"))
|
71
|
+
end
|
72
|
+
|
73
|
+
it "caches results when positional and keyword arguments are used" do
|
74
|
+
a = Object.new
|
75
|
+
expect(instance.qux(a, kwak: "kwav")).to eq(instance.qux(a, kwak: "kwav"))
|
76
|
+
end
|
77
|
+
|
78
|
+
it "caches results when keyword arguments are used" do
|
79
|
+
expect(instance.quux(kwak: "kwav")).to eq(instance.quux(kwak: "kwav"))
|
80
|
+
end
|
81
|
+
|
82
|
+
it "caches results when hash and keyword arguments are used" do
|
83
|
+
expect(instance.corge({ hash_key: "hash_value" }, kwak: "kwav")).to eq(instance.corge({ hash_key: "hash_value" }, kwak: "kwav"))
|
84
|
+
end
|
85
|
+
|
36
86
|
it "ignores cache when block given" do
|
37
87
|
expect(instance.foo { }).not_to eq(instance.foo { })
|
38
88
|
end
|
@@ -41,5 +91,51 @@ describe Memoit do
|
|
41
91
|
expect(instance).to receive(:foo).once
|
42
92
|
expect(instance.falsy).to eq(instance.falsy)
|
43
93
|
end
|
94
|
+
|
95
|
+
it "handles question-mark methods" do
|
96
|
+
expect(instance.query?).to eq(instance.query?)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "handles bang methods" do
|
100
|
+
expect(instance.bang!).to eq(instance.bang!)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "handles non-ASCII-name methods" do
|
104
|
+
expect(instance.☃).to eq(instance.☃)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "returns the name of the method" do
|
108
|
+
name = nil
|
109
|
+
Class.new do
|
110
|
+
name = memoize def blah
|
111
|
+
end
|
112
|
+
end
|
113
|
+
expect(name).to eq(:blah)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "works in a mixin" do
|
117
|
+
mod = Module.new do
|
118
|
+
memoize def cname
|
119
|
+
self.class.name
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
Foo = Class.new do
|
124
|
+
include mod
|
125
|
+
end
|
126
|
+
|
127
|
+
Bar = Class.new do
|
128
|
+
include mod
|
129
|
+
end
|
130
|
+
|
131
|
+
expect(Foo.new.cname).to eq("Foo")
|
132
|
+
expect(Bar.new.cname).to eq("Bar")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe ".memoize_class_method" do
|
137
|
+
it "caches result" do
|
138
|
+
expect(klass.foo).to eq(klass.foo)
|
139
|
+
end
|
44
140
|
end
|
45
141
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: memoit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Nicklas
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,49 +16,50 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '13.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '13.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '3.
|
47
|
+
version: '3.10'
|
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: '3.
|
55
|
-
description:
|
54
|
+
version: '3.10'
|
55
|
+
description:
|
56
56
|
email:
|
57
57
|
- jonas.nicklas@gmail.com
|
58
58
|
executables: []
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
+
- ".github/workflows/ci.yml"
|
62
63
|
- ".gitignore"
|
63
64
|
- Gemfile
|
64
65
|
- LICENSE.txt
|
@@ -72,7 +73,7 @@ homepage: ''
|
|
72
73
|
licenses:
|
73
74
|
- MIT
|
74
75
|
metadata: {}
|
75
|
-
post_install_message:
|
76
|
+
post_install_message:
|
76
77
|
rdoc_options: []
|
77
78
|
require_paths:
|
78
79
|
- lib
|
@@ -87,9 +88,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
88
|
- !ruby/object:Gem::Version
|
88
89
|
version: '0'
|
89
90
|
requirements: []
|
90
|
-
|
91
|
-
|
92
|
-
signing_key:
|
91
|
+
rubygems_version: 3.3.7
|
92
|
+
signing_key:
|
93
93
|
specification_version: 4
|
94
94
|
summary: Memoize is back!
|
95
95
|
test_files:
|