memo_wise 0.3.0 → 1.2.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/.dokaz +2 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +2 -2
- data/.github/dependabot.yml +20 -0
- data/.github/workflows/main.yml +21 -13
- data/.gitignore +1 -0
- data/.rubocop.yml +15 -0
- data/CHANGELOG.md +51 -3
- data/Gemfile +2 -1
- data/Gemfile.lock +25 -16
- data/LICENSE.txt +1 -1
- data/README.md +103 -32
- data/benchmarks/Gemfile +5 -3
- data/benchmarks/benchmarks.rb +163 -100
- data/lib/memo_wise/internal_api.rb +252 -0
- data/lib/memo_wise/version.rb +1 -1
- data/lib/memo_wise.rb +314 -267
- data/memo_wise.gemspec +6 -1
- metadata +9 -9
- data/.dependabot/config.yml +0 -13
- data/.github/workflows/auto-approve-dependabot.yml +0 -26
- data/.github/workflows/remove-needs-qa.yml +0 -35
- data/benchmarks/.ruby-version +0 -1
- data/benchmarks/Gemfile.lock +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a2fbbb2a403502d6a492068a9a0c8c103f717ea5b32e5029ba1a0aebab61db6
|
4
|
+
data.tar.gz: c2c8118caa1621670b6cd666f92147eb5c3f069c7b910062ed0f635568764dd7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 699415e3445e60bf6037fdb6887a064a4d082159be15c8c52a0711be5b3b233e3a7caa974f6d31df769d9bd0c3825d7a9f11b17b1e3b98ec9202ee8224801204
|
7
|
+
data.tar.gz: f6f377da39902d30310e7304e0caa7195e372c5fe0666e05ea30d2c2f936f3cc7d00c3588e453d5ab4ba7393a4f747f5c328acd4f4024cfa126ecb5f683fd24c
|
data/.dokaz
ADDED
@@ -1,4 +1,4 @@
|
|
1
1
|
**Before merging:**
|
2
2
|
|
3
|
-
- [ ] Copy the latest benchmark results into the `README.md` and update this PR
|
4
|
-
- [ ] If this change merits an update to `CHANGELOG.md`, add an entry following Keep a Changelog [guidelines](https://keepachangelog.com/en/1.0.0/) with [semantic versioning](https://semver.org/)
|
3
|
+
- [ ] Copy the table printed at the end of the latest benchmark results into the `README.md` and update this PR
|
4
|
+
- [ ] If this change merits an update to `CHANGELOG.md`, add an entry following Keep a Changelog [guidelines](https://keepachangelog.com/en/1.0.0/) with [semantic versioning](https://semver.org/)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
version: 2
|
2
|
+
|
3
|
+
updates:
|
4
|
+
# Maintain dependencies for Ruby's Bundler
|
5
|
+
- package-ecosystem: bundler
|
6
|
+
directory: "/"
|
7
|
+
schedule:
|
8
|
+
interval: daily
|
9
|
+
|
10
|
+
# Maintain dependencies for Ruby's Bundler (for Benchmarks!)
|
11
|
+
- package-ecosystem: bundler
|
12
|
+
directory: "/benchmarks"
|
13
|
+
schedule:
|
14
|
+
interval: daily
|
15
|
+
|
16
|
+
# Maintain dependencies for GitHub Actions
|
17
|
+
- package-ecosystem: "github-actions"
|
18
|
+
directory: "/"
|
19
|
+
schedule:
|
20
|
+
interval: "daily"
|
data/.github/workflows/main.yml
CHANGED
@@ -15,26 +15,34 @@ jobs:
|
|
15
15
|
ruby: [jruby, 2.4, 2.5, 2.6, 2.7, 3.0]
|
16
16
|
runs-on: ubuntu-latest
|
17
17
|
steps:
|
18
|
-
- uses: actions/checkout@
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
|
20
|
+
# Conditionally configure bundler via environment variables as advised
|
21
|
+
# * https://github.com/ruby/setup-ruby#bundle-config
|
22
|
+
- name: Set bundler environment variables
|
23
|
+
run: |
|
24
|
+
echo "BUNDLE_WITHOUT=checks:docs" >> $GITHUB_ENV
|
25
|
+
if: matrix.ruby != 3.0
|
26
|
+
|
27
|
+
# Use 'bundler-cache: true' instead of actions/cache as advised:
|
28
|
+
# * https://github.com/actions/cache/blob/main/examples.md#ruby---bundler
|
19
29
|
- uses: ruby/setup-ruby@v1
|
20
30
|
with:
|
21
31
|
ruby-version: ${{ matrix.ruby }}
|
22
|
-
|
23
|
-
|
24
|
-
path: vendor/bundle
|
25
|
-
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
|
26
|
-
restore-keys: |
|
27
|
-
${{ runner.os }}-gems-
|
28
|
-
- run: bundle config path vendor/bundle
|
29
|
-
- run: bundle config set without 'checks:docs'
|
30
|
-
if: matrix.ruby != 3.0
|
31
|
-
- run: bundle install --jobs 4 --retry 3
|
32
|
+
bundler-cache: true
|
33
|
+
|
32
34
|
- run: bundle exec rspec
|
35
|
+
|
33
36
|
- run: bundle exec rubocop
|
34
37
|
if: matrix.ruby == 3.0
|
35
|
-
|
36
|
-
if: matrix.ruby == 3.0
|
38
|
+
|
37
39
|
- run: |
|
40
|
+
bundle exec yard doctest
|
41
|
+
bundle exec dokaz
|
42
|
+
if: matrix.ruby == 3.0
|
43
|
+
|
44
|
+
- name: Run benchmarks on Ruby 2.7 or 3.0
|
45
|
+
run: |
|
38
46
|
BUNDLE_GEMFILE=benchmarks/Gemfile bundle install --jobs 4 --retry 3
|
39
47
|
BUNDLE_GEMFILE=benchmarks/Gemfile bundle exec ruby benchmarks/benchmarks.rb
|
40
48
|
if: matrix.ruby == '2.7' || matrix.ruby == '3.0'
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,2 +1,17 @@
|
|
1
1
|
inherit_gem:
|
2
2
|
panolint: rubocop.yml
|
3
|
+
|
4
|
+
Layout/LineLength:
|
5
|
+
Max: 120
|
6
|
+
|
7
|
+
Metrics/ModuleLength:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Metrics/PerceivedComplexity:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/DocumentDynamicEvalDefinition:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/MultipleComparison:
|
17
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -5,8 +5,53 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
-
##
|
9
|
-
|
8
|
+
## Unreleased
|
9
|
+
- Nothing yet!
|
10
|
+
|
11
|
+
## [1.2.0] - 2021-11-10
|
12
|
+
|
13
|
+
### Updated
|
14
|
+
- Improved performance of all methods by using an outer Array instead of a Hash
|
15
|
+
- Improved performance for multi-argument methods and simplify internal data
|
16
|
+
structures
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
- Removed use of #hash due to potential of hash collisions
|
20
|
+
- Updated internal local variable names to avoid name collisions with method
|
21
|
+
arguments
|
22
|
+
|
23
|
+
### Breaking Changes
|
24
|
+
- None
|
25
|
+
|
26
|
+
## [1.1.0] - 2021-07-29
|
27
|
+
### Updated
|
28
|
+
- Improved performance across the board by:
|
29
|
+
- removing `Hash#fetch`
|
30
|
+
- using `Array#hash`
|
31
|
+
- avoiding multi-layer hash lookups for multi-argument methods
|
32
|
+
- optimizing for truthy results
|
33
|
+
- Add `dry-core` to benchmarks in README
|
34
|
+
|
35
|
+
### Fixed
|
36
|
+
- Fixed usage on module singleton classes
|
37
|
+
- Fixed usage on module which would be extended by other classes
|
38
|
+
|
39
|
+
### Breaking Changes
|
40
|
+
- None
|
41
|
+
|
42
|
+
## [1.0.0] - 2021-06-24
|
43
|
+
### Added
|
44
|
+
- Support for `.preset_memo_wise` on class methods
|
45
|
+
- Support for `.reset_memo_wise` on class methods
|
46
|
+
|
47
|
+
### Updated
|
48
|
+
- Improved performance for common cases by reducing array allocations
|
49
|
+
|
50
|
+
## [0.4.0] - 2021-04-30
|
51
|
+
### Added
|
52
|
+
- Documentation of confusing module test behavior
|
53
|
+
- Support using MemoWise in classes with keyword arguments in the initializer
|
54
|
+
- Support Marshal dump/load of classes using MemoWise
|
10
55
|
|
11
56
|
## [0.3.0] - 2021-02-11
|
12
57
|
### Added
|
@@ -48,7 +93,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
48
93
|
- Panolint
|
49
94
|
- Dependabot setup
|
50
95
|
|
51
|
-
[Unreleased]: https://github.com/panorama-ed/memo_wise/compare/
|
96
|
+
[Unreleased]: https://github.com/panorama-ed/memo_wise/compare/v1.1.0...HEAD
|
97
|
+
[1.1.0]: https://github.com/panorama-ed/memo_wise/compare/v1.0.0...v1.1.0
|
98
|
+
[1.0.0]: https://github.com/panorama-ed/memo_wise/compare/v0.4.0...v1.0.0
|
99
|
+
[0.4.0]: https://github.com/panorama-ed/memo_wise/compare/v0.3.0...v0.4.0
|
52
100
|
[0.3.0]: https://github.com/panorama-ed/memo_wise/compare/v0.2.0...v0.3.0
|
53
101
|
[0.2.0]: https://github.com/panorama-ed/memo_wise/compare/v0.1.2...v0.2.0
|
54
102
|
[0.1.2]: https://github.com/panorama-ed/memo_wise/compare/v0.1.1...v0.1.2
|
data/Gemfile
CHANGED
@@ -14,11 +14,12 @@ end
|
|
14
14
|
# Excluded from CI except on latest MRI Ruby, to reduce compatibility burden
|
15
15
|
group :checks do
|
16
16
|
gem "codecov"
|
17
|
-
gem "panolint", github: "panorama-ed/panolint"
|
17
|
+
gem "panolint", github: "panorama-ed/panolint", branch: "main"
|
18
18
|
end
|
19
19
|
|
20
20
|
# Excluded from CI except on latest MRI Ruby, to reduce compatibility burden
|
21
21
|
group :docs do
|
22
|
+
gem "dokaz"
|
22
23
|
gem "redcarpet", "~> 3.5"
|
23
24
|
gem "yard", "~> 0.9"
|
24
25
|
gem "yard-doctest", "~> 0.1"
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
GIT
|
2
2
|
remote: https://github.com/panorama-ed/panolint.git
|
3
|
-
revision:
|
3
|
+
revision: c709ebcc5fd9593db959df4a92c12cae1d1fb9af
|
4
|
+
branch: main
|
4
5
|
specs:
|
5
|
-
panolint (0.1.
|
6
|
+
panolint (0.1.3)
|
6
7
|
brakeman (>= 4.8, < 6.0)
|
7
8
|
rubocop (>= 0.83, < 2.0)
|
8
9
|
rubocop-performance (~> 1.5)
|
@@ -13,35 +14,41 @@ GIT
|
|
13
14
|
PATH
|
14
15
|
remote: .
|
15
16
|
specs:
|
16
|
-
memo_wise (
|
17
|
+
memo_wise (1.2.0)
|
17
18
|
|
18
19
|
GEM
|
19
20
|
remote: https://rubygems.org/
|
20
21
|
specs:
|
21
|
-
activesupport (5.2.
|
22
|
+
activesupport (5.2.6)
|
22
23
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
23
24
|
i18n (>= 0.7, < 2)
|
24
25
|
minitest (~> 5.1)
|
25
26
|
tzinfo (~> 1.1)
|
27
|
+
ansi (1.5.0)
|
26
28
|
ast (2.4.2)
|
27
|
-
brakeman (5.
|
28
|
-
codecov (0.
|
29
|
+
brakeman (5.1.1)
|
30
|
+
codecov (0.6.0)
|
29
31
|
simplecov (>= 0.15, < 0.22)
|
30
|
-
concurrent-ruby (1.1.
|
32
|
+
concurrent-ruby (1.1.9)
|
31
33
|
diff-lcs (1.4.4)
|
32
34
|
docile (1.3.5)
|
33
|
-
|
35
|
+
dokaz (0.0.4)
|
36
|
+
ansi
|
37
|
+
rouge
|
38
|
+
slop (~> 3)
|
39
|
+
i18n (1.8.10)
|
34
40
|
concurrent-ruby (~> 1.0)
|
35
|
-
minitest (5.14.
|
41
|
+
minitest (5.14.4)
|
36
42
|
parallel (1.20.1)
|
37
|
-
parser (3.0.
|
43
|
+
parser (3.0.2.0)
|
38
44
|
ast (~> 2.4.1)
|
39
45
|
rack (2.2.3)
|
40
46
|
rainbow (3.0.0)
|
41
|
-
rake (13.0.
|
47
|
+
rake (13.0.6)
|
42
48
|
redcarpet (3.5.1)
|
43
|
-
regexp_parser (2.
|
44
|
-
rexml (3.2.
|
49
|
+
regexp_parser (2.1.1)
|
50
|
+
rexml (3.2.5)
|
51
|
+
rouge (3.26.0)
|
45
52
|
rspec (3.10.0)
|
46
53
|
rspec-core (~> 3.10.0)
|
47
54
|
rspec-expectations (~> 3.10.0)
|
@@ -55,7 +62,7 @@ GEM
|
|
55
62
|
diff-lcs (>= 1.2.0, < 2.0)
|
56
63
|
rspec-support (~> 3.10.0)
|
57
64
|
rspec-support (3.10.0)
|
58
|
-
rubocop (1.
|
65
|
+
rubocop (1.12.1)
|
59
66
|
parallel (~> 1.10)
|
60
67
|
parser (>= 3.0.0.0)
|
61
68
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -66,7 +73,7 @@ GEM
|
|
66
73
|
unicode-display_width (>= 1.4.0, < 3.0)
|
67
74
|
rubocop-ast (1.4.1)
|
68
75
|
parser (>= 2.7.1.5)
|
69
|
-
rubocop-performance (1.
|
76
|
+
rubocop-performance (1.10.2)
|
70
77
|
rubocop (>= 0.90.0, < 2.0)
|
71
78
|
rubocop-ast (>= 0.4.0)
|
72
79
|
rubocop-rails (2.9.1)
|
@@ -83,6 +90,7 @@ GEM
|
|
83
90
|
docile (~> 1.1)
|
84
91
|
simplecov-html (~> 0.11)
|
85
92
|
simplecov-html (0.12.3)
|
93
|
+
slop (3.6.0)
|
86
94
|
thread_safe (0.3.6)
|
87
95
|
tzinfo (1.2.9)
|
88
96
|
thread_safe (~> 0.1)
|
@@ -98,6 +106,7 @@ PLATFORMS
|
|
98
106
|
|
99
107
|
DEPENDENCIES
|
100
108
|
codecov
|
109
|
+
dokaz
|
101
110
|
memo_wise!
|
102
111
|
panolint!
|
103
112
|
rake
|
@@ -108,4 +117,4 @@ DEPENDENCIES
|
|
108
117
|
yard-doctest (~> 0.1)
|
109
118
|
|
110
119
|
BUNDLED WITH
|
111
|
-
2.2.
|
120
|
+
2.2.28
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2020 Panorama Education
|
3
|
+
Copyright (c) 2020-2021 Panorama Education
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -12,7 +12,6 @@
|
|
12
12
|
[](https://rubygems.org/gems/memo_wise)
|
13
13
|
[](https://rubygems.org/gems/memo_wise)
|
14
14
|
|
15
|
-
|
16
15
|
## Why `MemoWise`?
|
17
16
|
|
18
17
|
`MemoWise` is **the wise choice for Ruby memoization**, featuring:
|
@@ -51,11 +50,21 @@ methods:
|
|
51
50
|
```ruby
|
52
51
|
class Example
|
53
52
|
prepend MemoWise
|
53
|
+
|
54
54
|
def slow_value(x)
|
55
55
|
sleep x
|
56
56
|
x
|
57
57
|
end
|
58
58
|
memo_wise :slow_value
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# maintains privacy of the memoized method
|
63
|
+
def private_slow_method(x)
|
64
|
+
sleep x
|
65
|
+
x
|
66
|
+
end
|
67
|
+
memo_wise :private_slow_method
|
59
68
|
end
|
60
69
|
|
61
70
|
ex = Example.new
|
@@ -72,29 +81,68 @@ ex.slow_value(3) # => 4 # Returns immediately because the result is memoized
|
|
72
81
|
ex.reset_memo_wise # Resets all memoized results for all methods on ex
|
73
82
|
```
|
74
83
|
|
75
|
-
|
84
|
+
The same three methods are exposed for class methods as well:
|
76
85
|
|
77
|
-
|
86
|
+
```ruby
|
87
|
+
class Example
|
88
|
+
prepend MemoWise
|
78
89
|
|
79
|
-
|
90
|
+
def self.class_slow_value(x)
|
91
|
+
sleep x
|
92
|
+
x
|
93
|
+
end
|
94
|
+
memo_wise self: :class_slow_value
|
95
|
+
end
|
80
96
|
|
81
|
-
|
82
|
-
|
83
|
-
run on Ruby 3.0.0, except as indicated below for specific gems. Benchmarks are
|
84
|
-
run in GitHub Actions and updated in every PR that changes code.
|
97
|
+
Example.class_slow_value(2) # => 2 # Sleeps for 2 seconds before returning
|
98
|
+
Example.class_slow_value(2) # => 2 # Returns immediately because the result is memoized
|
85
99
|
|
86
|
-
|
87
|
-
|--|--|--|--|--|--|
|
88
|
-
|`()` (none)|**baseline**|14.69x slower|2.59x slower|1.15x slower|2.91x slower|
|
89
|
-
|`(a, b)`|**baseline**|1.93x slower|2.20x slower|1.79x slower|1.96x slower|
|
90
|
-
|`(a:, b:)`|**baseline**|3.01x slower|2.41x slower|2.18x slower|2.28x slower|
|
91
|
-
|`(a, b:)`|**baseline**|1.49x slower|1.75x slower|1.51x slower|1.60x slower|
|
92
|
-
|`(a, *args)`|**baseline**|1.92x slower|2.23x slower|1.94x slower|1.98x slower|
|
93
|
-
|`(a:, **kwargs)`|**baseline**|3.08x slower|2.48x slower|2.17x slower|2.28x slower|
|
94
|
-
|`(a, *args, b:, **kwargs)`|**baseline**|1.55x slower|1.73x slower|1.65x slower|1.67x slower|
|
100
|
+
Example.reset_memo_wise(:class_slow_value) # Resets all memoized results for class_slow_value
|
95
101
|
|
96
|
-
|
97
|
-
3
|
102
|
+
Example.preset_memo_wise(:class_slow_value, 3) { 4 } # Store 4 as the result for slow_value(3)
|
103
|
+
Example.class_slow_value(3) # => 4 # Returns immediately because the result is memoized
|
104
|
+
Example.reset_memo_wise # Resets all memoized results for all methods on class
|
105
|
+
```
|
106
|
+
|
107
|
+
**NOTE:** Methods which take implicit or explicit block arguments cannot be
|
108
|
+
memoized.
|
109
|
+
|
110
|
+
For more usage details, see our detailed [documentation](#documentation).
|
111
|
+
|
112
|
+
## Benchmarks
|
113
|
+
|
114
|
+
Benchmarks are run in GitHub Actions, and the tables below are updated with every code change. **Values >1.00x represent how much _slower_ each gem’s memoized value retrieval is than the latest commit of `MemoWise`**, according to [`benchmark-ips`](https://github.com/evanphx/benchmark-ips) (2.9.1).
|
115
|
+
|
116
|
+
Results using Ruby 3.0.2:
|
117
|
+
|
118
|
+
|Method arguments|`Dry::Core`\* (0.7.1)|`Memery` (1.4.0)|
|
119
|
+
|--|--|--|
|
120
|
+
|`()` (none)|1.51x|19.82x|
|
121
|
+
|`(a)`|2.30x|11.38x|
|
122
|
+
|`(a, b)`|0.45x|2.10x|
|
123
|
+
|`(a:)`|2.20x|22.83x|
|
124
|
+
|`(a:, b:)`|0.49x|4.53x|
|
125
|
+
|`(a, b:)`|0.46x|4.35x|
|
126
|
+
|`(a, *args)`|0.89x|2.03x|
|
127
|
+
|`(a:, **kwargs)`|0.82x|3.18x|
|
128
|
+
|`(a, *args, b:, **kwargs)`|0.60x|1.62x|
|
129
|
+
|
130
|
+
\* `Dry::Core`
|
131
|
+
[may cause incorrect behavior caused by hash collisions](https://github.com/dry-rb/dry-core/issues/63).
|
132
|
+
|
133
|
+
Results using Ruby 2.7.4 (because these gems raise errors in Ruby 3.x):
|
134
|
+
|
135
|
+
|Method arguments|`DDMemoize` (1.0.0)|`Memoist` (0.16.2)|`Memoized` (1.0.2)|`Memoizer` (1.0.3)|
|
136
|
+
|--|--|--|--|--|
|
137
|
+
|`()` (none)|35.29x|3.46x|1.67x|4.27x|
|
138
|
+
|`(a)`|25.04x|16.96x|12.83x|14.68x|
|
139
|
+
|`(a, b)`|3.20x|2.28x|1.84x|2.04x|
|
140
|
+
|`(a:)`|34.17x|27.77x|24.07x|25.39x|
|
141
|
+
|`(a:, b:)`|5.22x|4.29x|3.74x|4.00x|
|
142
|
+
|`(a, b:)`|4.81x|3.99x|3.49x|3.66x|
|
143
|
+
|`(a, *args)`|3.21x|2.30x|1.97x|2.00x|
|
144
|
+
|`(a:, **kwargs)`|2.84x|2.39x|2.12x|2.19x|
|
145
|
+
|`(a, *args, b:, **kwargs)`|2.10x|1.80x|1.67x|1.66x|
|
98
146
|
|
99
147
|
You can run benchmarks yourself with:
|
100
148
|
|
@@ -107,18 +155,6 @@ $ bundle exec ruby benchmarks.rb
|
|
107
155
|
If your results differ from what's posted here,
|
108
156
|
[let us know](https://github.com/panorama-ed/memo_wise/issues/new)!
|
109
157
|
|
110
|
-
## Development
|
111
|
-
|
112
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
113
|
-
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
114
|
-
prompt that will allow you to experiment.
|
115
|
-
|
116
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To
|
117
|
-
release a new version, update the version number in `version.rb`, and then run
|
118
|
-
`bundle exec rake release`, which will create a git tag for the version, push
|
119
|
-
git commits and tags, and push the `.gem` file to
|
120
|
-
[rubygems.org](https://rubygems.org).
|
121
|
-
|
122
158
|
## Documentation
|
123
159
|
|
124
160
|
### Documentation is Automatically Generated
|
@@ -141,6 +177,41 @@ code examples in our YARD documentation. To run `doctest` locally:
|
|
141
177
|
bundle exec yard doctest
|
142
178
|
```
|
143
179
|
|
180
|
+
We use [dokaz](https://github.com/zverok/dokaz) to test all code examples in
|
181
|
+
this README.md file, and all other non-code documentation. To run `dokaz`
|
182
|
+
locally:
|
183
|
+
|
184
|
+
```bash
|
185
|
+
bundle exec dokaz
|
186
|
+
```
|
187
|
+
|
188
|
+
### A Note on Testing
|
189
|
+
|
190
|
+
When testing memoized *module* methods, note that some testing setups will
|
191
|
+
reuse the same instance (which `include`s/`extend`s/`prepend`s the module)
|
192
|
+
across tests, which can result in confusing test failures when this differs from
|
193
|
+
how you use the code in production.
|
194
|
+
|
195
|
+
For example, Rails view helpers are modules that are commonly tested with a
|
196
|
+
[shared `view` instance](https://github.com/rails/rails/blob/291a3d2ef29a3842d1156ada7526f4ee60dd2b59/actionview/lib/action_view/test_case.rb#L203-L214). Rails initializes a new view instance for each web request so any view helper
|
197
|
+
methods would only be memoized for the duration of that web request, but in
|
198
|
+
tests (such as when using
|
199
|
+
[`rspec-rails`'s `helper`](https://github.com/rspec/rspec-rails/blob/main/lib/rspec/rails/example/helper_example_group.rb#L22-L27)),
|
200
|
+
the memoization may persist across tests. In this case, simply reset the
|
201
|
+
memoization between your tests with something like:
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
after(:each) { helper.reset_memo_wise }
|
205
|
+
```
|
206
|
+
|
207
|
+
## Further Reading
|
208
|
+
|
209
|
+
We've written more about MemoWise in a series of blog posts:
|
210
|
+
|
211
|
+
- [Introducing: MemoWise](https://medium.com/building-panorama-education/introducing-memowise-51a5f0523489)
|
212
|
+
- [Optimizing MemoWise Performance](https://ja.cob.land/optimizing-memowise-performance)
|
213
|
+
- [Esosteric Ruby in MemoWise](https://jemma.dev/blog/esoteric-ruby-in-memowise)
|
214
|
+
|
144
215
|
## Logo
|
145
216
|
|
146
217
|
`MemoWise`'s logo was created by [Luci Cooke](https://www.lucicooke.com/). The
|
@@ -162,7 +233,7 @@ To make a new release of `MemoWise` to
|
|
162
233
|
dependencies (e.g. `rake`) as follows:
|
163
234
|
|
164
235
|
```shell
|
165
|
-
bundle config
|
236
|
+
bundle config --local with 'release'
|
166
237
|
bundle install
|
167
238
|
```
|
168
239
|
|
data/benchmarks/Gemfile
CHANGED
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
4
|
|
5
|
-
ruby ">= 2.7.
|
5
|
+
ruby ">= 2.7.4"
|
6
6
|
|
7
|
-
gem "benchmark-ips", "2.
|
7
|
+
gem "benchmark-ips", "2.9.1"
|
8
8
|
|
9
9
|
if RUBY_VERSION > "3"
|
10
|
-
gem "
|
10
|
+
gem "dry-core", "0.7.1"
|
11
|
+
gem "memery", "1.4.0"
|
11
12
|
else
|
13
|
+
gem "ddmemoize", "1.0.0"
|
12
14
|
gem "memoist", "0.16.2"
|
13
15
|
gem "memoized", "1.0.2"
|
14
16
|
gem "memoizer", "1.0.3"
|