memoist3 1.0.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 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