memoist3 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a5a3431c7281f1d17a7c65861c9fb58e224b834c388774ad9a2f8e60e007b692
4
+ data.tar.gz: 96d5b1ba4fae250ad6b01f502041c9815e03868da2bc49cce47eb18c7ba821ea
5
+ SHA512:
6
+ metadata.gz: 65c4bf3637903fb83ea41f8b0a0a2a961d4ef5e733789f6cf5bdb2df65487fb515ae2deab75de6cdf70ab8ed5c743d6d4805d6f8cb2a79c0ce9ba88885689d98
7
+ data.tar.gz: 7df1a03a1951477837bbe5990c10e71045766f67ade3930b498ea4c6ae7fe9fc0599fff04badeb64f3008a0aa74f9fc61c6c743f614774328ab6dee2743376e3
@@ -0,0 +1,46 @@
1
+ name: ci
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ include:
12
+ - ruby: 2.7.2
13
+ - ruby: 2.7.5
14
+ - ruby: 3.0.1
15
+ - ruby: 3.0.3
16
+ - ruby: ruby-head
17
+ steps:
18
+ - uses: actions/checkout@v2
19
+ - name: Install rvm
20
+ run: |
21
+ curl -sSL https://get.rvm.io | bash
22
+ - name: Install ruby
23
+ run: |
24
+ source $HOME/.rvm/scripts/rvm
25
+ rvm use ${{ matrix.ruby }} --default --install --binary --fuzzy --create
26
+ - name: Check ruby version
27
+ run: |
28
+ source $HOME/.rvm/scripts/rvm
29
+ ruby --version
30
+ - name: Update rubygems
31
+ run: |
32
+ source $HOME/.rvm/scripts/rvm
33
+ gem update --system ${{ matrix.rubygems }}
34
+ - name: Install bundler
35
+ run: |
36
+ source $HOME/.rvm/scripts/rvm
37
+ gem install bundler --no-document -v '~> 1.13'
38
+ - name: Install gems
39
+ run: |
40
+ source $HOME/.rvm/scripts/rvm
41
+ bundle install --jobs 4
42
+ - run: unset JRUBY_OPTS
43
+ - name: Run rake
44
+ run: |
45
+ source $HOME/.rvm/scripts/rvm
46
+ bundle exec rake
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .ruby-version
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/CHANGELOG.md ADDED
@@ -0,0 +1,136 @@
1
+ # Changelog
2
+
3
+ ## [v1.0.0](https://github.com/honzasterba/memoist/tree/v0.16.2) (2022-01-09)
4
+
5
+ [Full Changelog](https://github.com/matthewrudy/honzasterba/compare/v0.16.1...v1.0.0)
6
+
7
+ - support for Ruby 3 kwargs
8
+
9
+ ## [v0.16.2](https://github.com/matthewrudy/memoist/tree/v0.16.2) (2019-12-04)
10
+
11
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.16.1...v0.16.2)
12
+
13
+ **Merged pull requests:**
14
+
15
+ - Fix regression introduced by frozen symbol fix [\#86](https://github.com/matthewrudy/memoist/pull/86) ([sebjacobs](https://github.com/sebjacobs))
16
+
17
+ ## [v0.16.1](https://github.com/matthewrudy/memoist/tree/v0.16.1) (2019-11-08)
18
+
19
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.16.0...v0.16.1)
20
+
21
+ **Merged pull requests:**
22
+
23
+ - Remove ruby 1.9.2 from travis build matrix [\#84](https://github.com/matthewrudy/memoist/pull/84) ([unasuke](https://github.com/unasuke))
24
+ - Make Memoist.escape\_punctuation compatible with MRI 2.7 [\#82](https://github.com/matthewrudy/memoist/pull/82) ([casperisfine](https://github.com/casperisfine))
25
+ - add 2.5.1 to travis [\#77](https://github.com/matthewrudy/memoist/pull/77) ([matthewrudy](https://github.com/matthewrudy))
26
+ - Remove ghit.me [\#74](https://github.com/matthewrudy/memoist/pull/74) ([matthewrudy](https://github.com/matthewrudy))
27
+ - Place sample code for execution in README.md [\#73](https://github.com/matthewrudy/memoist/pull/73) ([3nan3](https://github.com/3nan3))
28
+ - Require Ruby \>=1.9.2 [\#69](https://github.com/matthewrudy/memoist/pull/69) ([matthewrudy](https://github.com/matthewrudy))
29
+
30
+ ## [v0.16.0](https://github.com/matthewrudy/memoist/tree/v0.16.0) (2017-06-20)
31
+
32
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.15.0...v0.16.0)
33
+
34
+ **Merged pull requests:**
35
+
36
+ - Fix undefined `memoized\_methods` error raised when a parent class has not call `memoize` [\#68](https://github.com/matthewrudy/memoist/pull/68) ([PikachuEXE](https://github.com/PikachuEXE))
37
+ - Add support for class-level cache flushing. [\#67](https://github.com/matthewrudy/memoist/pull/67) ([JoeMcB](https://github.com/JoeMcB))
38
+ - Add ruby 2.4 to travis \(bump 2.2 and 2.3 versions\) [\#64](https://github.com/matthewrudy/memoist/pull/64) ([jrafanie](https://github.com/jrafanie))
39
+ - Fix tests for Ruby \< 1.9.3 [\#56](https://github.com/matthewrudy/memoist/pull/56) ([matthewrudy](https://github.com/matthewrudy))
40
+ - Add return in comments for `flush\_cache`. [\#55](https://github.com/matthewrudy/memoist/pull/55) ([joshuapinter](https://github.com/joshuapinter))
41
+ - Update readme [\#53](https://github.com/matthewrudy/memoist/pull/53) ([biow0lf](https://github.com/biow0lf))
42
+
43
+ ## [v0.15.0](https://github.com/matthewrudy/memoist/tree/v0.15.0) (2016-08-23)
44
+
45
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.14.0...v0.15.0)
46
+
47
+ **Merged pull requests:**
48
+
49
+ - Remove test warnings [\#52](https://github.com/matthewrudy/memoist/pull/52) ([matthewrudy](https://github.com/matthewrudy))
50
+ - Use SVG badge over PNG [\#44](https://github.com/matthewrudy/memoist/pull/44) ([olivierlacan](https://github.com/olivierlacan))
51
+
52
+ ## [v0.14.0](https://github.com/matthewrudy/memoist/tree/v0.14.0) (2015-12-15)
53
+
54
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.13.0...v0.14.0)
55
+
56
+ **Merged pull requests:**
57
+
58
+ - Faster2: Cache the method, ivar, and arity and the ancestry memoized methods [\#38](https://github.com/matthewrudy/memoist/pull/38) ([jrafanie](https://github.com/jrafanie))
59
+
60
+ ## [v0.13.0](https://github.com/matthewrudy/memoist/tree/v0.13.0) (2015-11-26)
61
+
62
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.12.0...v0.13.0)
63
+
64
+ **Merged pull requests:**
65
+
66
+ - Faster memoist with less object allocations [\#36](https://github.com/matthewrudy/memoist/pull/36) ([jrafanie](https://github.com/jrafanie))
67
+ - Be optimistic about bundler version [\#35](https://github.com/matthewrudy/memoist/pull/35) ([lotyrin](https://github.com/lotyrin))
68
+ - Add syntax highlighting for code blocks. [\#34](https://github.com/matthewrudy/memoist/pull/34) ([joshuapinter](https://github.com/joshuapinter))
69
+
70
+ ## [v0.12.0](https://github.com/matthewrudy/memoist/tree/v0.12.0) (2015-04-13)
71
+
72
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.11.0...v0.12.0)
73
+
74
+ **Merged pull requests:**
75
+
76
+ - Fix forking link [\#30](https://github.com/matthewrudy/memoist/pull/30) ([brandondrew](https://github.com/brandondrew))
77
+ - Update README with :identifier info [\#29](https://github.com/matthewrudy/memoist/pull/29) ([fervic](https://github.com/fervic))
78
+
79
+ ## [v0.11.0](https://github.com/matthewrudy/memoist/tree/v0.11.0) (2014-10-10)
80
+
81
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.10.0...v0.11.0)
82
+
83
+ **Merged pull requests:**
84
+
85
+ - Call abs on arity when extracting reload [\#27](https://github.com/matthewrudy/memoist/pull/27) ([bradylove](https://github.com/bradylove))
86
+
87
+ ## [v0.10.0](https://github.com/matthewrudy/memoist/tree/v0.10.0) (2014-08-13)
88
+
89
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.9.3...v0.10.0)
90
+
91
+ **Merged pull requests:**
92
+
93
+ - Make memoize return a :symbol [\#24](https://github.com/matthewrudy/memoist/pull/24) ([matthewrudy](https://github.com/matthewrudy))
94
+ - Use Minitest [\#19](https://github.com/matthewrudy/memoist/pull/19) ([matthewrudy](https://github.com/matthewrudy))
95
+
96
+ ## [v0.9.3](https://github.com/matthewrudy/memoist/tree/v0.9.3) (2014-06-01)
97
+
98
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.9.2...v0.9.3)
99
+
100
+ **Merged pull requests:**
101
+
102
+ - Remove Array caching hack [\#17](https://github.com/matthewrudy/memoist/pull/17) ([matthewrudy](https://github.com/matthewrudy))
103
+
104
+ ## [v0.9.2](https://github.com/matthewrudy/memoist/tree/v0.9.2) (2014-04-16)
105
+
106
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/0.9.0...v0.9.2)
107
+
108
+ **Merged pull requests:**
109
+
110
+ - Give double-memoize errors their own error class [\#15](https://github.com/matthewrudy/memoist/pull/15) ([zachhale](https://github.com/zachhale))
111
+ - Add tax-themed example for class method memoization fixes \#9 [\#10](https://github.com/matthewrudy/memoist/pull/10) ([fny](https://github.com/fny))
112
+
113
+ ## [0.9.0](https://github.com/matthewrudy/memoist/tree/0.9.0) (2013-03-20)
114
+
115
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/0.2.0...0.9.0)
116
+
117
+ **Merged pull requests:**
118
+
119
+ - Update README.md to include memoization bypass description [\#6](https://github.com/matthewrudy/memoist/pull/6) ([andreychernih](https://github.com/andreychernih))
120
+ - Adds a note about the MIT License [\#4](https://github.com/matthewrudy/memoist/pull/4) ([matiaskorhonen](https://github.com/matiaskorhonen))
121
+
122
+ ## [0.2.0](https://github.com/matthewrudy/memoist/tree/0.2.0) (2012-08-15)
123
+
124
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/0.1.0...0.2.0)
125
+
126
+ **Merged pull requests:**
127
+
128
+ - Improved performance of flush\_cache and prime\_cache when parameters are passed to them. [\#2](https://github.com/matthewrudy/memoist/pull/2) ([jrafanie](https://github.com/jrafanie))
129
+
130
+ ## [0.1.0](https://github.com/matthewrudy/memoist/tree/0.1.0) (2012-01-24)
131
+
132
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/7a5352d6b6c4219f37f329d2422985961c749748...0.1.0)
133
+
134
+
135
+
136
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in memoist.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012-2013 Matthew Rudy Jacobs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,172 @@
1
+ This is a fork of the original repo by [matthewrudy](https://github.com/matthewrudy/memoist)
2
+ adapted for usage with Ruby 3.
3
+
4
+ # Memoist
5
+
6
+ [![Gem Version](https://badge.fury.io/rb/memoist3.svg)](https://badge.fury.io/rb/memoist3)
7
+ [![Build Status](https://github.com/honzasterba/memoist/workflows/ci/badge.svg)](https://github.com/honzasterba/memoist/actions)
8
+
9
+ Memoist is an extraction of ActiveSupport::Memoizable.
10
+
11
+ Since June 2011 ActiveSupport::Memoizable has been deprecated.
12
+ But I love it, and so I plan to keep it alive.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ bundle add memoist3
18
+ ```
19
+
20
+ or
21
+
22
+ ```ruby
23
+ gem 'memoist3'
24
+ ```
25
+
26
+ ## Supported Rubies
27
+
28
+ This library supports
29
+
30
+ - MRI Ruby 2 (>= 2.7.2)
31
+ - MRI Ruby 3 (>= 3.0.0)
32
+
33
+ ## Usage
34
+
35
+ Just extend with the Memoist module
36
+
37
+ ```ruby
38
+ require 'memoist'
39
+ class Person
40
+ extend Memoist
41
+
42
+ def social_security
43
+ puts "execute!"
44
+ decrypt_social_security
45
+ end
46
+ memoize :social_security
47
+ end
48
+
49
+ person = Person.new
50
+
51
+ person.social_security
52
+ # execute!
53
+ # => (returns decrypt_social_security)
54
+
55
+ person.social_security
56
+ # => (returns the memoized value)
57
+ ```
58
+
59
+ And person.social_security will only be calculated once.
60
+
61
+ Every memoized function (which initially was not accepting any arguments) has a `(reload)`
62
+ argument you can pass in to bypass and reset the memoization:
63
+
64
+ ```ruby
65
+ def some_method
66
+ Time.now
67
+ end
68
+ memoize :some_method
69
+ ```
70
+
71
+ Calling `some_method` will be memoized, but calling `some_method(true)` will rememoize each time.
72
+
73
+ You can even memoize method that takes arguments.
74
+
75
+ ```ruby
76
+ class Person
77
+ def taxes_due(income)
78
+ income * 0.40
79
+ end
80
+ memoize :taxes_due
81
+ end
82
+ ```
83
+
84
+ This will only be calculated once per value of income.
85
+
86
+ You can also memoize class methods.
87
+
88
+ ```ruby
89
+ class Person
90
+
91
+ class << self
92
+ extend Memoist
93
+ def with_overdue_taxes
94
+ # ...
95
+ end
96
+ memoize :with_overdue_taxes
97
+ end
98
+
99
+ end
100
+ ```
101
+
102
+ When a sub-class overrides one of its parent's methods and you need to memoize both.
103
+ Then you can use the `:identifier` parameter in order to help _Memoist_ distinguish between the two.
104
+
105
+ ```ruby
106
+ class Clock
107
+ extend Memoist
108
+ def now
109
+ "The time now is #{Time.now.hour} o'clock and #{Time.now.min} minutes"
110
+ end
111
+ memoize :now
112
+ end
113
+
114
+ class AccurateClock < Clock
115
+ extend Memoist
116
+ def now
117
+ "#{super} and #{Time.now.sec} seconds"
118
+ end
119
+ memoize :now, :identifier => :accurate_clock
120
+ end
121
+ ```
122
+
123
+ ## Reload
124
+
125
+ Each memoized function comes with a way to flush the existing value.
126
+
127
+ ```ruby
128
+ person.social_security # returns the memoized value
129
+ person.social_security(true) # bypasses the memoized value and rememoizes it
130
+ ```
131
+
132
+ This also works with a memoized method with arguments
133
+
134
+ ```ruby
135
+ person.taxes_due(100_000) # returns the memoized value
136
+ person.taxes_due(100_000, true) # bypasses the memoized value and rememoizes it
137
+ ```
138
+
139
+ If you want to flush the entire memoization cache for an object
140
+
141
+ ```ruby
142
+ person.flush_cache # returns an array of flushed memoized methods, e.g. ["social_security", "some_method"]
143
+ ```
144
+
145
+ # Authors
146
+
147
+ Everyone who contributed to it in the rails repository.
148
+
149
+ - Joshua Peek
150
+ - Tarmo Tänav
151
+ - Jeremy Kemper
152
+ - Eugene Pimenov
153
+ - Xavier Noria
154
+ - Niels Ganser
155
+ - Carl Lerche & Yehuda Katz
156
+ - jeem
157
+ - Jay Pignata
158
+ - Damien Mathieu
159
+ - José Valim
160
+ - Matthew Rudy Jacobs
161
+
162
+ # Contributing
163
+
164
+ 1. Fork it ( https://github.com/honzasterba/memoist/fork )
165
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
166
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
167
+ 4. Push to the branch (`git push origin my-new-feature`)
168
+ 5. Create new Pull Request
169
+
170
+ # License
171
+
172
+ Released under the [MIT License](http://www.opensource.org/licenses/MIT), just as Ruby on Rails is.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+
5
+ require 'rake/testtask'
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'test'
8
+ t.test_files = FileList['test/**/*_test.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task default: ['test']
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Memoist
4
+ VERSION = '1.0.0'
5
+ end
data/lib/memoist.rb ADDED
@@ -0,0 +1,238 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'memoist/version'
4
+
5
+ module Memoist
6
+ def self.extended(extender)
7
+ Memoist.memoist_eval(extender) do
8
+ unless singleton_class.method_defined?(:memoized_methods)
9
+ def self.memoized_methods
10
+ @_memoized_methods ||= []
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ def self.memoized_ivar_for(method_name, identifier = nil)
17
+ "@#{memoized_prefix(identifier)}_#{escape_punctuation(method_name)}"
18
+ end
19
+
20
+ def self.unmemoized_method_for(method_name, identifier = nil)
21
+ "#{unmemoized_prefix(identifier)}_#{method_name}".to_sym
22
+ end
23
+
24
+ def self.memoized_prefix(identifier = nil)
25
+ if identifier
26
+ "_memoized_#{identifier}"
27
+ else
28
+ '_memoized'.freeze
29
+ end
30
+ end
31
+
32
+ def self.unmemoized_prefix(identifier = nil)
33
+ if identifier
34
+ "_unmemoized_#{identifier}"
35
+ else
36
+ '_unmemoized'.freeze
37
+ end
38
+ end
39
+
40
+ def self.escape_punctuation(string)
41
+ string = string.is_a?(String) ? string.dup : string.to_s.dup
42
+
43
+ return string unless string.end_with?('?'.freeze, '!'.freeze)
44
+
45
+ # A String can't end in both ? and !
46
+ if string.sub!(/\?\Z/, '_query'.freeze)
47
+ else
48
+ string.sub!(/!\Z/, '_bang'.freeze)
49
+ end
50
+ string
51
+ end
52
+
53
+ def self.memoist_eval(klass, *args, **kwargs, &block)
54
+ if klass.respond_to?(:class_eval)
55
+ klass.class_eval(*args, **kwargs, &block)
56
+ else
57
+ klass.singleton_class.class_eval(*args, **kwargs, &block)
58
+ end
59
+ end
60
+
61
+ def self.extract_reload!(method, args)
62
+ if args.length == method.arity.abs + 1 && (args.last == true || args.last == :reload)
63
+ reload = args.pop
64
+ end
65
+ reload
66
+ end
67
+
68
+ module InstanceMethods
69
+ def memoize_all
70
+ prime_cache
71
+ end
72
+
73
+ def unmemoize_all
74
+ flush_cache
75
+ end
76
+
77
+ def memoized_structs(names)
78
+ ref_obj = self.class.respond_to?(:class_eval) ? singleton_class : self
79
+ structs = ref_obj.all_memoized_structs
80
+ return structs if names.empty?
81
+
82
+ structs.select { |s| names.include?(s.memoized_method) }
83
+ end
84
+
85
+ def prime_cache(*method_names)
86
+ memoized_structs(method_names).each do |struct|
87
+ if struct.arity == 0
88
+ __send__(struct.memoized_method)
89
+ else
90
+ instance_variable_set(struct.ivar, {})
91
+ end
92
+ end
93
+ end
94
+
95
+ def flush_cache(*method_names)
96
+ memoized_structs(method_names).each do |struct|
97
+ remove_instance_variable(struct.ivar) if instance_variable_defined?(struct.ivar)
98
+ end
99
+ end
100
+ end
101
+
102
+ MemoizedMethod = Struct.new(:memoized_method, :ivar, :arity)
103
+
104
+ def all_memoized_structs
105
+ @all_memoized_structs ||= begin
106
+ structs = memoized_methods.dup
107
+
108
+ # Collect the memoized_methods of ancestors in ancestor order
109
+ # unless we already have it since self or parents could be overriding
110
+ # an ancestor method.
111
+ ancestors.grep(Memoist).each do |ancestor|
112
+ ancestor.memoized_methods.each do |m|
113
+ structs << m unless structs.any? { |am| am.memoized_method == m.memoized_method }
114
+ end
115
+ end
116
+ structs
117
+ end
118
+ end
119
+
120
+ def clear_structs
121
+ @all_memoized_structs = nil
122
+ end
123
+
124
+ def memoize(*method_names)
125
+ identifier = method_names.pop[:identifier] if method_names.last.is_a?(Hash)
126
+
127
+ method_names.each do |method_name|
128
+ unmemoized_method = Memoist.unmemoized_method_for(method_name, identifier)
129
+ memoized_ivar = Memoist.memoized_ivar_for(method_name, identifier)
130
+
131
+ Memoist.memoist_eval(self) do
132
+ include InstanceMethods
133
+
134
+ if method_defined?(unmemoized_method)
135
+ warn "Already memoized #{method_name}"
136
+ return
137
+ end
138
+ alias_method unmemoized_method, method_name
139
+
140
+ mm = MemoizedMethod.new(method_name, memoized_ivar, instance_method(method_name).arity)
141
+ memoized_methods << mm
142
+ if mm.arity == 0
143
+
144
+ # define a method like this;
145
+
146
+ # def mime_type(reload=true)
147
+ # skip_cache = reload || !instance_variable_defined?("@_memoized_mime_type")
148
+ # set_cache = skip_cache && !frozen?
149
+ #
150
+ # if skip_cache
151
+ # value = _unmemoized_mime_type
152
+ # else
153
+ # value = @_memoized_mime_type
154
+ # end
155
+ #
156
+ # if set_cache
157
+ # @_memoized_mime_type = value
158
+ # end
159
+ #
160
+ # value
161
+ # end
162
+
163
+ module_eval <<-EOS, __FILE__, __LINE__ + 1
164
+ def #{method_name}(reload = false)
165
+ skip_cache = reload || !instance_variable_defined?("#{memoized_ivar}")
166
+ set_cache = skip_cache && !frozen?
167
+
168
+ if skip_cache
169
+ value = #{unmemoized_method}
170
+ else
171
+ value = #{memoized_ivar}
172
+ end
173
+
174
+ if set_cache
175
+ #{memoized_ivar} = value
176
+ end
177
+
178
+ value
179
+ end
180
+ EOS
181
+ else
182
+
183
+ # define a method like this;
184
+
185
+ # def mime_type(*args)
186
+ # reload = Memoist.extract_reload!(method(:_unmemoized_mime_type), args)
187
+ #
188
+ # skip_cache = reload || !memoized_with_args?(:mime_type, args)
189
+ # set_cache = skip_cache && !frozen
190
+ #
191
+ # if skip_cache
192
+ # value = _unmemoized_mime_type(*args)
193
+ # else
194
+ # value = @_memoized_mime_type[args]
195
+ # end
196
+ #
197
+ # if set_cache
198
+ # @_memoized_mime_type ||= {}
199
+ # @_memoized_mime_type[args] = value
200
+ # end
201
+ #
202
+ # value
203
+ # end
204
+
205
+ module_eval <<-EOS, __FILE__, __LINE__ + 1
206
+ def #{method_name}(*args, **kwargs)
207
+ reload = Memoist.extract_reload!(method(#{unmemoized_method.inspect}), args)
208
+
209
+ skip_cache = reload || !(instance_variable_defined?(#{memoized_ivar.inspect}) && #{memoized_ivar} && #{memoized_ivar}.has_key?(args+kwargs.to_a))
210
+ set_cache = skip_cache && !frozen?
211
+
212
+ if skip_cache
213
+ value = #{unmemoized_method}(*args, **kwargs)
214
+ else
215
+ value = #{memoized_ivar}[args+kwargs.to_a]
216
+ end
217
+
218
+ if set_cache
219
+ #{memoized_ivar} ||= {}
220
+ #{memoized_ivar}[args+kwargs.to_a] = value
221
+ end
222
+
223
+ value
224
+ end
225
+ EOS
226
+ end
227
+
228
+ if private_method_defined?(unmemoized_method)
229
+ private method_name
230
+ elsif protected_method_defined?(unmemoized_method)
231
+ protected method_name
232
+ end
233
+ end
234
+ end
235
+ # return a chainable method_name symbol if we can
236
+ method_names.length == 1 ? method_names.first : method_names
237
+ end
238
+ end