memoist 0.11.0 → 0.16.2

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
- SHA1:
3
- metadata.gz: ae4871b19ddf0826d00aed6706f6d4e18e87b1fc
4
- data.tar.gz: 9f51de9a63090ec5e42ec3e17ca3188776f537a7
2
+ SHA256:
3
+ metadata.gz: '058dae917e46d13306497f0bcd18df607cb1d5dca2d85ee6f9cbc18739172e27'
4
+ data.tar.gz: c0874b135f70db573a863e4b54bb141905c003d9e451d7c3637d8f67c96a0696
5
5
  SHA512:
6
- metadata.gz: e2d53081c9d2c4041458aedd80ef01f4ac4933882edb08315081a8ec7846ef9dcad9730a8a21458a78ad78bc913c94ca6fd06f55376706b1c0ead43254090b91
7
- data.tar.gz: 5ae1ffcf79b52f2d9b52aa59d66eeeaf7f1b1ad80a247d4549ac902ef1e2e7bdcc70c6429974faba32f085d5a5b0d859d5288927a043528718ce00d7c0ad0f55
6
+ metadata.gz: 409f37c0861015cc81704bf4fbbb1002d7a011a5f3dccb0e1430baf8b5eac601f5caae99cf4e1634fe044ea01123c1a0319692fad6d64c848026329f9a4dfa7a
7
+ data.tar.gz: 7f3134101c02c37ce88fd6a814c6bce19f5ffc4085fcfbb08e22ce720f125b7f8c2c2644c6a694cf4bb5dc4feb40974785f1209d598c18ba098bc055bca33146
data/.travis.yml CHANGED
@@ -1,17 +1,21 @@
1
+ sudo: false
2
+ cache: bundler
1
3
  language: ruby
2
4
  rvm:
3
- - 1.8.7
4
- - 1.9.2
5
5
  - 1.9.3
6
6
  - 2.0.0
7
- - 2.1.0
8
- - jruby-18mode
9
- - jruby-19mode
10
- - rbx-2
7
+ - 2.1.10
8
+ - 2.2.7
9
+ - 2.3.4
10
+ - 2.4.1
11
+ - 2.5.1
12
+ - 2.6.0
11
13
  - ruby-head
14
+ - jruby-19mode
15
+ - jruby-9.1.9.0
12
16
  - jruby-head
13
- - ree
14
- matrix:
15
- allow_failures:
16
- - rvm: ruby-head
17
- - rvm: jruby-head
17
+
18
+ before_install:
19
+ - gem install bundler --no-document -v '~> 1.13'
20
+ before_script:
21
+ - unset JRUBY_OPTS
data/CHANGELOG.md ADDED
@@ -0,0 +1,130 @@
1
+ # Changelog
2
+
3
+ ## [Unreleased](https://github.com/matthewrudy/memoist/tree/HEAD)
4
+
5
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.16.1...HEAD)
6
+
7
+ **Merged pull requests:**
8
+
9
+ - Fix regression introduced by frozen symbol fix [\#86](https://github.com/matthewrudy/memoist/pull/86) ([sebjacobs](https://github.com/sebjacobs))
10
+
11
+ ## [v0.16.1](https://github.com/matthewrudy/memoist/tree/v0.16.1) (2019-11-08)
12
+
13
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.16.0...v0.16.1)
14
+
15
+ **Merged pull requests:**
16
+
17
+ - Remove ruby 1.9.2 from travis build matrix [\#84](https://github.com/matthewrudy/memoist/pull/84) ([unasuke](https://github.com/unasuke))
18
+ - Make Memoist.escape\_punctuation compatible with MRI 2.7 [\#82](https://github.com/matthewrudy/memoist/pull/82) ([casperisfine](https://github.com/casperisfine))
19
+ - add 2.5.1 to travis [\#77](https://github.com/matthewrudy/memoist/pull/77) ([matthewrudy](https://github.com/matthewrudy))
20
+ - Remove ghit.me [\#74](https://github.com/matthewrudy/memoist/pull/74) ([matthewrudy](https://github.com/matthewrudy))
21
+ - Place sample code for execution in README.md [\#73](https://github.com/matthewrudy/memoist/pull/73) ([3nan3](https://github.com/3nan3))
22
+ - Require Ruby \>=1.9.2 [\#69](https://github.com/matthewrudy/memoist/pull/69) ([matthewrudy](https://github.com/matthewrudy))
23
+
24
+ ## [v0.16.0](https://github.com/matthewrudy/memoist/tree/v0.16.0) (2017-06-20)
25
+
26
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.15.0...v0.16.0)
27
+
28
+ **Merged pull requests:**
29
+
30
+ - 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))
31
+ - Add support for class-level cache flushing. [\#67](https://github.com/matthewrudy/memoist/pull/67) ([JoeMcB](https://github.com/JoeMcB))
32
+ - 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))
33
+ - Fix tests for Ruby \< 1.9.3 [\#56](https://github.com/matthewrudy/memoist/pull/56) ([matthewrudy](https://github.com/matthewrudy))
34
+ - Add return in comments for `flush\_cache`. [\#55](https://github.com/matthewrudy/memoist/pull/55) ([joshuapinter](https://github.com/joshuapinter))
35
+ - Update readme [\#53](https://github.com/matthewrudy/memoist/pull/53) ([biow0lf](https://github.com/biow0lf))
36
+
37
+ ## [v0.15.0](https://github.com/matthewrudy/memoist/tree/v0.15.0) (2016-08-23)
38
+
39
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.14.0...v0.15.0)
40
+
41
+ **Merged pull requests:**
42
+
43
+ - Remove test warnings [\#52](https://github.com/matthewrudy/memoist/pull/52) ([matthewrudy](https://github.com/matthewrudy))
44
+ - Use SVG badge over PNG [\#44](https://github.com/matthewrudy/memoist/pull/44) ([olivierlacan](https://github.com/olivierlacan))
45
+
46
+ ## [v0.14.0](https://github.com/matthewrudy/memoist/tree/v0.14.0) (2015-12-15)
47
+
48
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.13.0...v0.14.0)
49
+
50
+ **Merged pull requests:**
51
+
52
+ - 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))
53
+
54
+ ## [v0.13.0](https://github.com/matthewrudy/memoist/tree/v0.13.0) (2015-11-26)
55
+
56
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.12.0...v0.13.0)
57
+
58
+ **Merged pull requests:**
59
+
60
+ - Faster memoist with less object allocations [\#36](https://github.com/matthewrudy/memoist/pull/36) ([jrafanie](https://github.com/jrafanie))
61
+ - Be optimistic about bundler version [\#35](https://github.com/matthewrudy/memoist/pull/35) ([lotyrin](https://github.com/lotyrin))
62
+ - Add syntax highlighting for code blocks. [\#34](https://github.com/matthewrudy/memoist/pull/34) ([joshuapinter](https://github.com/joshuapinter))
63
+
64
+ ## [v0.12.0](https://github.com/matthewrudy/memoist/tree/v0.12.0) (2015-04-13)
65
+
66
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.11.0...v0.12.0)
67
+
68
+ **Merged pull requests:**
69
+
70
+ - Fix forking link [\#30](https://github.com/matthewrudy/memoist/pull/30) ([brandondrew](https://github.com/brandondrew))
71
+ - Update README with :identifier info [\#29](https://github.com/matthewrudy/memoist/pull/29) ([fervic](https://github.com/fervic))
72
+
73
+ ## [v0.11.0](https://github.com/matthewrudy/memoist/tree/v0.11.0) (2014-10-10)
74
+
75
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.10.0...v0.11.0)
76
+
77
+ **Merged pull requests:**
78
+
79
+ - Call abs on arity when extracting reload [\#27](https://github.com/matthewrudy/memoist/pull/27) ([bradylove](https://github.com/bradylove))
80
+
81
+ ## [v0.10.0](https://github.com/matthewrudy/memoist/tree/v0.10.0) (2014-08-13)
82
+
83
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.9.3...v0.10.0)
84
+
85
+ **Merged pull requests:**
86
+
87
+ - Make memoize return a :symbol [\#24](https://github.com/matthewrudy/memoist/pull/24) ([matthewrudy](https://github.com/matthewrudy))
88
+ - Use Minitest [\#19](https://github.com/matthewrudy/memoist/pull/19) ([matthewrudy](https://github.com/matthewrudy))
89
+
90
+ ## [v0.9.3](https://github.com/matthewrudy/memoist/tree/v0.9.3) (2014-06-01)
91
+
92
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/v0.9.2...v0.9.3)
93
+
94
+ **Merged pull requests:**
95
+
96
+ - Remove Array caching hack [\#17](https://github.com/matthewrudy/memoist/pull/17) ([matthewrudy](https://github.com/matthewrudy))
97
+
98
+ ## [v0.9.2](https://github.com/matthewrudy/memoist/tree/v0.9.2) (2014-04-16)
99
+
100
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/0.9.0...v0.9.2)
101
+
102
+ **Merged pull requests:**
103
+
104
+ - Give double-memoize errors their own error class [\#15](https://github.com/matthewrudy/memoist/pull/15) ([zachhale](https://github.com/zachhale))
105
+ - Add tax-themed example for class method memoization fixes \#9 [\#10](https://github.com/matthewrudy/memoist/pull/10) ([fny](https://github.com/fny))
106
+
107
+ ## [0.9.0](https://github.com/matthewrudy/memoist/tree/0.9.0) (2013-03-20)
108
+
109
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/0.2.0...0.9.0)
110
+
111
+ **Merged pull requests:**
112
+
113
+ - Update README.md to include memoization bypass description [\#6](https://github.com/matthewrudy/memoist/pull/6) ([andreychernih](https://github.com/andreychernih))
114
+ - Adds a note about the MIT License [\#4](https://github.com/matthewrudy/memoist/pull/4) ([matiaskorhonen](https://github.com/matiaskorhonen))
115
+
116
+ ## [0.2.0](https://github.com/matthewrudy/memoist/tree/0.2.0) (2012-08-15)
117
+
118
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/0.1.0...0.2.0)
119
+
120
+ **Merged pull requests:**
121
+
122
+ - 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))
123
+
124
+ ## [0.1.0](https://github.com/matthewrudy/memoist/tree/0.1.0) (2012-01-24)
125
+
126
+ [Full Changelog](https://github.com/matthewrudy/memoist/compare/7a5352d6b6c4219f37f329d2422985961c749748...0.1.0)
127
+
128
+
129
+
130
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  Memoist
2
2
  =============
3
3
 
4
- [![Build Status](https://travis-ci.org/matthewrudy/memoist.png?branch=master)](https://travis-ci.org/matthewrudy/memoist)
4
+ [![Build Status](https://travis-ci.org/matthewrudy/memoist.svg?branch=master)](https://travis-ci.org/matthewrudy/memoist)
5
5
 
6
6
  Memoist is an extraction of ActiveSupport::Memoizable.
7
7
 
@@ -14,53 +14,91 @@ Usage
14
14
 
15
15
  Just extend with the Memoist module
16
16
 
17
- require 'memoist'
18
- class Person
19
- extend Memoist
17
+ ```ruby
18
+ require 'memoist'
19
+ class Person
20
+ extend Memoist
20
21
 
21
- def social_security
22
- decrypt_social_security
23
- end
24
- memoize :social_security
25
- end
22
+ def social_security
23
+ puts "execute!"
24
+ decrypt_social_security
25
+ end
26
+ memoize :social_security
27
+ end
28
+
29
+ person = Person.new
30
+
31
+ person.social_security
32
+ # execute!
33
+ # => (returns decrypt_social_security)
34
+
35
+ person.social_security
36
+ # => (returns the memoized value)
37
+ ```
26
38
 
27
39
  And person.social_security will only be calculated once.
28
40
 
29
41
  Every memoized function (which initially was not accepting any arguments) has a ```(reload)```
30
42
  argument you can pass in to bypass and reset the memoization:
31
43
 
32
- def some_method
33
- Time.now
34
- end
35
- memoize :some_method
44
+ ```ruby
45
+ def some_method
46
+ Time.now
47
+ end
48
+ memoize :some_method
49
+ ```
36
50
 
37
51
  Calling ```some_method``` will be memoized, but calling ```some_method(true)``` will rememoize each time.
38
52
 
39
53
  You can even memoize method that takes arguments.
40
54
 
41
-
42
- class Person
43
- def taxes_due(income)
44
- income * 0.40
45
- end
46
- memoize :taxes_due
47
- end
55
+ ```ruby
56
+ class Person
57
+ def taxes_due(income)
58
+ income * 0.40
59
+ end
60
+ memoize :taxes_due
61
+ end
62
+ ```
48
63
 
49
64
  This will only be calculated once per value of income.
50
65
 
51
66
  You can also memoize class methods.
52
67
 
53
- class Person
54
-
55
- class << self
56
- extend Memoist
57
- def with_overdue_taxes
58
- # ...
59
- end
60
- memoize :with_overdue_taxes
61
- end
68
+ ```ruby
69
+ class Person
62
70
 
71
+ class << self
72
+ extend Memoist
73
+ def with_overdue_taxes
74
+ # ...
63
75
  end
76
+ memoize :with_overdue_taxes
77
+ end
78
+
79
+ end
80
+ ```
81
+
82
+ When a sub-class overrides one of its parent's methods and you need to memoize both.
83
+ Then you can use the `:identifier` parameter in order to help _Memoist_ distinguish between the two.
84
+
85
+ ```ruby
86
+ class Clock
87
+ extend Memoist
88
+ def now
89
+ "The time now is #{Time.now.hour} o'clock and #{Time.now.min} minutes"
90
+ end
91
+ memoize :now
92
+ end
93
+
94
+ class AccurateClock < Clock
95
+ extend Memoist
96
+ def now
97
+ "#{super} and #{Time.now.sec} seconds"
98
+ end
99
+ memoize :now, :identifier => :accurate_clock
100
+ end
101
+ ```
64
102
 
65
103
 
66
104
  Reload
@@ -68,17 +106,23 @@ Reload
68
106
 
69
107
  Each memoized function comes with a way to flush the existing value.
70
108
 
71
- person.social_security # returns the memoized value
72
- person.social_security(true) # bypasses the memoized value and rememoizes it
109
+ ```ruby
110
+ person.social_security # returns the memoized value
111
+ person.social_security(true) # bypasses the memoized value and rememoizes it
112
+ ```
73
113
 
74
114
  This also works with a memoized method with arguments
75
115
 
76
- person.taxes_due(100_000) # returns the memoized value
77
- person.taxes_due(100_000, true) # bypasses the memoized value and rememoizes it
116
+ ```ruby
117
+ person.taxes_due(100_000) # returns the memoized value
118
+ person.taxes_due(100_000, true) # bypasses the memoized value and rememoizes it
119
+ ```
78
120
 
79
121
  If you want to flush the entire memoization cache for an object
80
122
 
81
- person.flush_cache
123
+ ```ruby
124
+ person.flush_cache # returns an array of flushed memoized methods, e.g. ["social_security", "some_method"]
125
+ ```
82
126
 
83
127
  Authors
84
128
  ===========
@@ -101,7 +145,7 @@ Everyone who contributed to it in the rails repository.
101
145
  Contributing
102
146
  ============
103
147
 
104
- 1. Fork it ( http://github.com/<my-github-username>/memoist/fork )
148
+ 1. Fork it ( https://github.com/matthewrudy/memoist/fork )
105
149
  2. Create your feature branch (`git checkout -b my-new-feature`)
106
150
  3. Commit your changes (`git commit -am 'Add some feature'`)
107
151
  4. Push to the branch (`git push origin my-new-feature`)
data/Rakefile CHANGED
@@ -1,11 +1,12 @@
1
1
  # encoding: utf-8
2
- require "bundler/gem_tasks"
3
2
 
4
- require "rake/testtask"
3
+ require 'bundler/gem_tasks'
4
+
5
+ require 'rake/testtask'
5
6
  Rake::TestTask.new do |t|
6
- t.libs << "test"
7
- t.test_files = FileList["test/**/*_test.rb"]
7
+ t.libs << 'test'
8
+ t.test_files = FileList['test/**/*_test.rb']
8
9
  t.verbose = true
9
10
  end
10
11
 
11
- task :default => ["test"]
12
+ task default: ['test']
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Memoist
2
- VERSION = "0.11.0"
4
+ VERSION = '0.16.2'.freeze
3
5
  end
data/lib/memoist.rb CHANGED
@@ -1,25 +1,53 @@
1
- require 'memoist/core_ext/singleton_class'
1
+ # frozen_string_literal: true
2
+
3
+ require 'memoist/version'
2
4
 
3
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
4
15
 
5
- def self.memoized_ivar_for(method_name, identifier=nil)
6
- ["@#{memoized_prefix(identifier)}", escape_punctuation(method_name.to_s)].join("_")
16
+ def self.memoized_ivar_for(method_name, identifier = nil)
17
+ "@#{memoized_prefix(identifier)}_#{escape_punctuation(method_name)}"
7
18
  end
8
19
 
9
- def self.unmemoized_method_for(method_name, identifier=nil)
10
- [unmemoized_prefix(identifier), method_name].join("_").to_sym
20
+ def self.unmemoized_method_for(method_name, identifier = nil)
21
+ "#{unmemoized_prefix(identifier)}_#{method_name}".to_sym
11
22
  end
12
23
 
13
- def self.memoized_prefix(identifier=nil)
14
- ["_memoized", identifier].compact.join("_")
24
+ def self.memoized_prefix(identifier = nil)
25
+ if identifier
26
+ "_memoized_#{identifier}"
27
+ else
28
+ '_memoized'.freeze
29
+ end
15
30
  end
16
31
 
17
- def self.unmemoized_prefix(identifier=nil)
18
- ["_unmemoized", identifier].compact.join("_")
32
+ def self.unmemoized_prefix(identifier = nil)
33
+ if identifier
34
+ "_unmemoized_#{identifier}"
35
+ else
36
+ '_unmemoized'.freeze
37
+ end
19
38
  end
20
39
 
21
40
  def self.escape_punctuation(string)
22
- string.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')
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
23
51
  end
24
52
 
25
53
  def self.memoist_eval(klass, *args, &block)
@@ -46,47 +74,55 @@ module Memoist
46
74
  flush_cache
47
75
  end
48
76
 
49
- def prime_cache(*method_names)
50
- if method_names.empty?
51
- prefix = Memoist.unmemoized_prefix+"_"
52
- method_names = methods.collect do |method_name|
53
- if method_name.to_s.start_with?(prefix)
54
- method_name[prefix.length..-1]
55
- end
56
- end.compact
57
- end
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
58
84
 
59
- method_names.each do |method_name|
60
- if method(Memoist.unmemoized_method_for(method_name)).arity == 0
61
- __send__(method_name)
85
+ def prime_cache(*method_names)
86
+ memoized_structs(method_names).each do |struct|
87
+ if struct.arity == 0
88
+ __send__(struct.memoized_method)
62
89
  else
63
- ivar = Memoist.memoized_ivar_for(method_name)
64
- instance_variable_set(ivar, {})
90
+ instance_variable_set(struct.ivar, {})
65
91
  end
66
92
  end
67
93
  end
68
94
 
69
95
  def flush_cache(*method_names)
70
- if method_names.empty?
71
- prefix = Memoist.unmemoized_prefix+"_"
72
- method_names = (methods + private_methods + protected_methods).collect do |method_name|
73
- if method_name.to_s.start_with?(prefix)
74
- method_name[prefix.length..-1]
75
- end
76
- end.compact
96
+ memoized_structs(method_names).each do |struct|
97
+ remove_instance_variable(struct.ivar) if instance_variable_defined?(struct.ivar)
77
98
  end
99
+ end
100
+ end
101
+
102
+ MemoizedMethod = Struct.new(:memoized_method, :ivar, :arity)
78
103
 
79
- method_names.each do |method_name|
80
- ivar = Memoist.memoized_ivar_for(method_name)
81
- remove_instance_variable(ivar) if instance_variable_defined?(ivar)
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
82
115
  end
116
+ structs
83
117
  end
84
118
  end
85
119
 
120
+ def clear_structs
121
+ @all_memoized_structs = nil
122
+ end
123
+
86
124
  def memoize(*method_names)
87
- if method_names.last.is_a?(Hash)
88
- identifier = method_names.pop[:identifier]
89
- end
125
+ identifier = method_names.pop[:identifier] if method_names.last.is_a?(Hash)
90
126
 
91
127
  method_names.each do |method_name|
92
128
  unmemoized_method = Memoist.unmemoized_method_for(method_name, identifier)
@@ -96,11 +132,14 @@ module Memoist
96
132
  include InstanceMethods
97
133
 
98
134
  if method_defined?(unmemoized_method)
99
- raise AlreadyMemoizedError.new("Already memoized #{method_name}")
135
+ warn "Already memoized #{method_name}"
136
+ return
100
137
  end
101
138
  alias_method unmemoized_method, method_name
102
139
 
103
- if instance_method(method_name).arity == 0
140
+ mm = MemoizedMethod.new(method_name, memoized_ivar, instance_method(method_name).arity)
141
+ memoized_methods << mm
142
+ if mm.arity == 0
104
143
 
105
144
  # define a method like this;
106
145
 
@@ -196,6 +235,4 @@ module Memoist
196
235
  # return a chainable method_name symbol if we can
197
236
  method_names.length == 1 ? method_names.first : method_names
198
237
  end
199
-
200
- class AlreadyMemoizedError < RuntimeError; end
201
238
  end
data/memoist.gemspec CHANGED
@@ -1,38 +1,46 @@
1
1
  # coding: utf-8
2
+
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'memoist/version'
5
6
 
6
7
  AUTHORS = [
7
- ["Joshua Peek", "josh@joshpeek.com"],
8
- ["Tarmo Tänav", "tarmo@itech.ee"],
9
- ["Jeremy Kemper", "jeremy@bitsweat.net"],
10
- ["Eugene Pimenov", "libc@mac.com"],
11
- ["Xavier Noria", "fxn@hashref.com"],
12
- ["Niels Ganser", "niels@herimedia.co"],
13
- ["Carl Lerche & Yehuda Katz", "wycats@gmail.com"],
14
- ["jeem", "jeem@hughesorama.com"],
15
- ["Jay Pignata", "john.pignata@gmail.com"],
16
- ["Damien Mathieu", "42@dmathieu.com"],
17
- ["José Valim", "jose.valim@gmail.com"],
18
- ["Matthew Rudy Jacobs", "matthewrudyjacobs@gmail.com"],
19
- ]
8
+ ['Joshua Peek', 'josh@joshpeek.com'],
9
+ ['Tarmo Tänav', 'tarmo@itech.ee'],
10
+ ['Jeremy Kemper', 'jeremy@bitsweat.net'],
11
+ ['Eugene Pimenov', 'libc@mac.com'],
12
+ ['Xavier Noria', 'fxn@hashref.com'],
13
+ ['Niels Ganser', 'niels@herimedia.co'],
14
+ ['Carl Lerche & Yehuda Katz', 'wycats@gmail.com'],
15
+ ['jeem', 'jeem@hughesorama.com'],
16
+ ['Jay Pignata', 'john.pignata@gmail.com'],
17
+ ['Damien Mathieu', '42@dmathieu.com'],
18
+ ['José Valim', 'jose.valim@gmail.com'],
19
+ ['Matthew Rudy Jacobs', 'matthewrudyjacobs@gmail.com']
20
+ ].freeze
20
21
 
21
22
  Gem::Specification.new do |spec|
22
- spec.name = "memoist"
23
+ spec.name = 'memoist'
23
24
  spec.version = Memoist::VERSION
24
- spec.authors = AUTHORS.map{ |name, email| name }
25
- spec.email = AUTHORS.map{ |name, email| email }
26
- spec.summary = %q{memoize methods invocation}
27
- spec.homepage = "https://github.com/matthewrudy/memoist"
28
- spec.license = "MIT"
25
+ spec.authors = AUTHORS.map { |name, _email| name }
26
+ spec.email = AUTHORS.map { |_name, email| email }
27
+ spec.summary = 'memoize methods invocation'
28
+ spec.homepage = 'https://github.com/matthewrudy/memoist'
29
+ spec.license = 'MIT'
29
30
 
30
31
  spec.files = `git ls-files -z`.split("\x0")
31
32
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
33
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
33
- spec.require_paths = ["lib"]
34
+ spec.require_paths = ['lib']
35
+
36
+ spec.required_ruby_version = '>= 1.9.2'
34
37
 
35
- spec.add_development_dependency "bundler", "~> 1.5"
36
- spec.add_development_dependency "rake"
37
- spec.add_development_dependency "minitest", "~> 3.0"
38
+ spec.add_development_dependency 'benchmark-ips'
39
+ spec.add_development_dependency 'bundler'
40
+ if RUBY_VERSION < '1.9.3'
41
+ spec.add_development_dependency 'rake', '~> 10.4'
42
+ else
43
+ spec.add_development_dependency 'rake'
44
+ end
45
+ spec.add_development_dependency 'minitest', '~> 5.10'
38
46
  end
@@ -0,0 +1,48 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
2
+ require 'benchmark/ips'
3
+
4
+ require 'memoist'
5
+
6
+ class Benchy
7
+ extend Memoist
8
+
9
+ def arity_0
10
+ 'Hello World'
11
+ end
12
+ memoize :arity_0
13
+
14
+ def arity_1(name)
15
+ "Hello #{name}"
16
+ end
17
+ memoize :arity_1
18
+ end
19
+
20
+ OBJECT = Benchy.new
21
+
22
+ puts "Benchmarking: #{Memoist::VERSION}"
23
+
24
+ Benchmark.ips do |x|
25
+ x.report('arity 0 - memoized') do |times|
26
+ times.times do
27
+ OBJECT.arity_0
28
+ end
29
+ end
30
+
31
+ # x.report("arity 0 - unmemoized") do |times|
32
+ # times.times do
33
+ # OBJECT._unmemoized_arity_0
34
+ # end
35
+ # end
36
+
37
+ x.report('arity 1 - memoized') do |times|
38
+ times.times do
39
+ OBJECT.arity_1(:World)
40
+ end
41
+ end
42
+
43
+ # x.report("arity 1 - unmemoized") do |times|
44
+ # times.times do
45
+ # OBJECT._unmemoized_arity_1(:World)
46
+ # end
47
+ # end
48
+ end
data/test/memoist_test.rb CHANGED
@@ -1,10 +1,8 @@
1
1
  require 'test_helper'
2
2
  require 'memoist'
3
3
 
4
- class MemoistTest < Minitest::Unit::TestCase
5
-
4
+ class MemoistTest < Minitest::Test
6
5
  class CallCounter
7
-
8
6
  def initialize
9
7
  @calls = {}
10
8
  end
@@ -17,7 +15,6 @@ class MemoistTest < Minitest::Unit::TestCase
17
15
  def count(method_name)
18
16
  @calls[method_name] ||= 0
19
17
  end
20
-
21
18
  end
22
19
 
23
20
  class Person
@@ -49,7 +46,7 @@ class MemoistTest < Minitest::Unit::TestCase
49
46
 
50
47
  def name
51
48
  @counter.call(:name)
52
- "Josh"
49
+ 'Josh'
53
50
  end
54
51
 
55
52
  def name?
@@ -58,8 +55,8 @@ class MemoistTest < Minitest::Unit::TestCase
58
55
  end
59
56
  memoize :name?
60
57
 
61
- def update(name)
62
- "Joshua"
58
+ def update(_name)
59
+ 'Joshua'
63
60
  end
64
61
  memoize :update
65
62
 
@@ -70,6 +67,12 @@ class MemoistTest < Minitest::Unit::TestCase
70
67
 
71
68
  memoize :name, :age
72
69
 
70
+ def age?
71
+ @counter.call(:age?)
72
+ true
73
+ end
74
+ memoize 'age?'
75
+
73
76
  def sleep(hours = 8)
74
77
  @counter.call(:sleep)
75
78
  hours
@@ -80,7 +83,7 @@ class MemoistTest < Minitest::Unit::TestCase
80
83
  @counter.count(:sleep)
81
84
  end
82
85
 
83
- def update_attributes(options = {})
86
+ def update_attributes(_options = {})
84
87
  @counter.call(:update_attributes)
85
88
  true
86
89
  end
@@ -101,7 +104,7 @@ class MemoistTest < Minitest::Unit::TestCase
101
104
 
102
105
  def is_developer?
103
106
  @counter.call(:is_developer?)
104
- "Yes"
107
+ 'Yes'
105
108
  end
106
109
  memoize :is_developer?
107
110
  end
@@ -111,7 +114,14 @@ class MemoistTest < Minitest::Unit::TestCase
111
114
  @counter.call(:student_name)
112
115
  "Student #{super}"
113
116
  end
114
- memoize :name, :identifier => :student
117
+ memoize :name, identifier: :student
118
+ end
119
+
120
+ class Teacher < Person
121
+ def seniority
122
+ 'very_senior'
123
+ end
124
+ memoize :seniority
115
125
  end
116
126
 
117
127
  class Company
@@ -122,7 +132,7 @@ class MemoistTest < Minitest::Unit::TestCase
122
132
 
123
133
  def name
124
134
  @name_calls += 1
125
- "37signals"
135
+ '37signals'
126
136
  end
127
137
  end
128
138
 
@@ -174,16 +184,68 @@ class MemoistTest < Minitest::Unit::TestCase
174
184
  memoize :counter
175
185
  end
176
186
 
187
+ class Book
188
+ extend Memoist
189
+ STATUSES = %w[new used].freeze
190
+ CLASSIFICATION = %w[fiction nonfiction].freeze
191
+ GENRES = %w[humor romance reference sci-fi classic philosophy].freeze
192
+
193
+ attr_reader :title, :author
194
+ def initialize(title, author)
195
+ @title = title
196
+ @author = author
197
+ end
198
+
199
+ def full_title
200
+ "#{@title} by #{@author}"
201
+ end
202
+ memoize :full_title
203
+
204
+ class << self
205
+ extend Memoist
206
+
207
+ def all_types
208
+ STATUSES.product(CLASSIFICATION).product(GENRES).collect(&:flatten)
209
+ end
210
+ memoize :all_types
211
+ end
212
+ end
213
+
214
+ class Abb
215
+ extend Memoist
216
+
217
+ def run(*_args)
218
+ flush_cache if respond_to?(:flush_cache)
219
+ execute
220
+ end
221
+
222
+ def execute
223
+ some_method
224
+ end
225
+
226
+ def some_method
227
+ # Override this
228
+ end
229
+ end
230
+
231
+ class Bbb < Abb
232
+ def some_method
233
+ :foo
234
+ end
235
+ memoize :some_method
236
+ end
237
+
177
238
  def setup
178
239
  @person = Person.new
179
240
  @calculator = Calculator.new
241
+ @book = Book.new('My Life', "Brian 'Fudge' Turmuck")
180
242
  end
181
243
 
182
244
  def test_memoization
183
- assert_equal "Josh", @person.name
245
+ assert_equal 'Josh', @person.name
184
246
  assert_equal 1, @person.name_calls
185
247
 
186
- 3.times { assert_equal "Josh", @person.name }
248
+ 3.times { assert_equal 'Josh', @person.name }
187
249
  assert_equal 1, @person.name_calls
188
250
  end
189
251
 
@@ -199,13 +261,13 @@ class MemoistTest < Minitest::Unit::TestCase
199
261
  end
200
262
 
201
263
  def test_memoize_with_options_hash
202
- assert_equal true, @person.update_attributes(:age => 21, :name => 'James')
264
+ assert_equal true, @person.update_attributes(age: 21, name: 'James')
203
265
  assert_equal 1, @person.update_attributes_calls
204
266
 
205
- 3.times { assert_equal true, @person.update_attributes(:age => 21, :name => 'James') }
267
+ 3.times { assert_equal true, @person.update_attributes(age: 21, name: 'James') }
206
268
  assert_equal 1, @person.update_attributes_calls
207
269
 
208
- 3.times { assert_equal true, @person.update_attributes({:age => 21, :name => 'James'}, :reload) }
270
+ 3.times { assert_equal true, @person.update_attributes({ age: 21, name: 'James' }, :reload) }
209
271
  assert_equal 4, @person.update_attributes_calls
210
272
  end
211
273
 
@@ -216,6 +278,13 @@ class MemoistTest < Minitest::Unit::TestCase
216
278
  @person.unmemoize_all
217
279
  end
218
280
 
281
+ def test_memoization_when_memoize_is_called_with_punctuated_string
282
+ assert_equal true, @person.age?
283
+
284
+ @person.memoize_all
285
+ @person.unmemoize_all
286
+ end
287
+
219
288
  def test_memoization_flush_with_punctuation
220
289
  assert_equal true, @person.name?
221
290
  @person.flush_cache(:name?)
@@ -224,10 +293,10 @@ class MemoistTest < Minitest::Unit::TestCase
224
293
  end
225
294
 
226
295
  def test_memoization_with_nil_value
227
- assert_equal nil, @person.age
296
+ assert_nil @person.age
228
297
  assert_equal 1, @person.age_calls
229
298
 
230
- 3.times { assert_equal nil, @person.age }
299
+ 3.times { assert_nil @person.age }
231
300
  assert_equal 1, @person.age_calls
232
301
  end
233
302
 
@@ -244,26 +313,116 @@ class MemoistTest < Minitest::Unit::TestCase
244
313
 
245
314
  assert @calculator.instance_variable_get(:@_memoized_counter)
246
315
  @calculator.flush_cache(:counter)
247
- assert_nil @calculator.instance_variable_get(:@_memoized_counter)
248
- assert !@calculator.instance_variable_defined?(:@_memoized_counter)
316
+ assert_equal false, @calculator.instance_variable_defined?(:@_memoized_counter)
249
317
 
250
318
  assert_equal 2, @calculator.counter
251
319
  end
252
320
 
321
+ def test_class_flush_cache
322
+ @book.memoize_all
323
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.full_title
324
+
325
+ Book.memoize_all
326
+ assert_instance_of Array, Book.instance_variable_get(:@_memoized_all_types)
327
+ Book.flush_cache
328
+ assert_equal false, Book.instance_variable_defined?(:@_memoized_all_types)
329
+ end
330
+
331
+ def test_class_flush_cache_preserves_instances
332
+ @book.memoize_all
333
+ Book.memoize_all
334
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.full_title
335
+
336
+ Book.flush_cache
337
+ assert_equal false, Book.instance_variable_defined?(:@_memoized_all_types)
338
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.full_title
339
+ end
340
+
341
+ def test_flush_cache_in_child_class
342
+ x = Bbb.new
343
+
344
+ # This should not throw error
345
+ x.run
346
+ end
347
+
253
348
  def test_unmemoize_all
254
349
  assert_equal 1, @calculator.counter
255
350
 
351
+ assert_equal true, @calculator.instance_variable_defined?(:@_memoized_counter)
256
352
  assert @calculator.instance_variable_get(:@_memoized_counter)
257
353
  @calculator.unmemoize_all
258
- assert_nil @calculator.instance_variable_get(:@_memoized_counter)
259
- assert !@calculator.instance_variable_defined?(:@_memoized_counter)
354
+ assert_equal false, @calculator.instance_variable_defined?(:@_memoized_counter)
260
355
 
261
356
  assert_equal 2, @calculator.counter
262
357
  end
263
358
 
359
+ def test_all_memoized_structs
360
+ # Person memoize :age, :age?, :is_developer?, :memoize_protected_test, :name, :name?, :sleep, :update, :update_attributes
361
+ # Student < Person memoize :name, :identifier => :student
362
+ # Teacher < Person memoize :seniority
363
+
364
+ expected = %w[age age? is_developer? memoize_protected_test name name? sleep update update_attributes]
365
+ structs = Person.all_memoized_structs
366
+ assert_equal expected, structs.collect(&:memoized_method).collect(&:to_s).sort
367
+ assert_equal '@_memoized_name', structs.detect { |s| s.memoized_method == :name }.ivar
368
+
369
+ # Same expected methods
370
+ structs = Student.all_memoized_structs
371
+ assert_equal expected, structs.collect(&:memoized_method).collect(&:to_s).sort
372
+ assert_equal '@_memoized_student_name', structs.detect { |s| s.memoized_method == :name }.ivar
373
+
374
+ expected = (expected << 'seniority').sort
375
+ structs = Teacher.all_memoized_structs
376
+ assert_equal expected, structs.collect(&:memoized_method).collect(&:to_s).sort
377
+ assert_equal '@_memoized_name', structs.detect { |s| s.memoized_method == :name }.ivar
378
+ end
379
+
380
+ def test_unmemoize_all_subclasses
381
+ # Person memoize :age, :is_developer?, :memoize_protected_test, :name, :name?, :sleep, :update, :update_attributes
382
+ # Student < Person memoize :name, :identifier => :student
383
+ # Teacher < Person memoize :seniority
384
+
385
+ teacher = Teacher.new
386
+ assert_equal 'Josh', teacher.name
387
+ assert_equal 'Josh', teacher.instance_variable_get(:@_memoized_name)
388
+ assert_equal 'very_senior', teacher.seniority
389
+ assert_equal 'very_senior', teacher.instance_variable_get(:@_memoized_seniority)
390
+
391
+ teacher.unmemoize_all
392
+ assert_equal false, teacher.instance_variable_defined?(:@_memoized_name)
393
+ assert_equal false, teacher.instance_variable_defined?(:@_memoized_seniority)
394
+
395
+ student = Student.new
396
+ assert_equal 'Student Josh', student.name
397
+ assert_equal 'Student Josh', student.instance_variable_get(:@_memoized_student_name)
398
+ assert_equal false, student.instance_variable_defined?(:@_memoized_seniority)
399
+
400
+ student.unmemoize_all
401
+ assert_equal false, @calculator.instance_variable_defined?(:@_memoized_student_name)
402
+ end
403
+
264
404
  def test_memoize_all
265
405
  @calculator.memoize_all
266
- assert @calculator.instance_variable_defined?(:@_memoized_counter)
406
+ assert_equal true, @calculator.instance_variable_defined?(:@_memoized_counter)
407
+ end
408
+
409
+ def test_memoize_all_subclasses
410
+ # Person memoize :age, :is_developer?, :memoize_protected_test, :name, :name?, :sleep, :update, :update_attributes
411
+ # Student < Person memoize :name, :identifier => :student
412
+ # Teacher < Person memoize :seniority
413
+
414
+ teacher = Teacher.new
415
+ teacher.memoize_all
416
+
417
+ assert_equal 'very_senior', teacher.instance_variable_get(:@_memoized_seniority)
418
+ assert_equal 'Josh', teacher.instance_variable_get(:@_memoized_name)
419
+
420
+ student = Student.new
421
+ student.memoize_all
422
+
423
+ assert_equal 'Student Josh', student.instance_variable_get(:@_memoized_student_name)
424
+ assert_equal 'Student Josh', student.name
425
+ assert_equal false, student.instance_variable_defined?(:@_memoized_seniority)
267
426
  end
268
427
 
269
428
  def test_memoization_cache_is_different_for_each_instance
@@ -272,10 +431,20 @@ class MemoistTest < Minitest::Unit::TestCase
272
431
  assert_equal 1, Calculator.new.counter
273
432
  end
274
433
 
434
+ def test_memoization_class_variables
435
+ @book.memoize_all
436
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.instance_variable_get(:@_memoized_full_title)
437
+ assert_equal "My Life by Brian 'Fudge' Turmuck", @book.full_title
438
+
439
+ Book.memoize_all
440
+ assert_instance_of Array, Book.instance_variable_get(:@_memoized_all_types)
441
+ assert_equal 24, Book.all_types.count
442
+ end
443
+
275
444
  def test_memoized_is_not_affected_by_freeze
276
445
  @person.freeze
277
- assert_equal "Josh", @person.name
278
- assert_equal "Joshua", @person.update("Joshua")
446
+ assert_equal 'Josh', @person.name
447
+ assert_equal 'Joshua', @person.update('Joshua')
279
448
  end
280
449
 
281
450
  def test_memoization_with_args
@@ -302,9 +471,9 @@ class MemoistTest < Minitest::Unit::TestCase
302
471
  company.extend Memoist
303
472
  company.memoize :name
304
473
 
305
- assert_equal "37signals", company.name
474
+ assert_equal '37signals', company.name
306
475
  assert_equal 1, company.name_calls
307
- assert_equal "37signals", company.name
476
+ assert_equal '37signals', company.name
308
477
  assert_equal 1, company.name_calls
309
478
  end
310
479
  end
@@ -330,20 +499,30 @@ class MemoistTest < Minitest::Unit::TestCase
330
499
  assert_equal 2, company.sales_tax_calls
331
500
  end
332
501
 
333
- def test_double_memoization
334
- assert_raises(Memoist::AlreadyMemoizedError) { Person.memoize :name }
335
- person = Person.new
336
- person.extend Memoist
337
- assert_raises(Memoist::AlreadyMemoizedError) { person.memoize :name }
338
-
339
- company = Company.new
340
- company.extend Memoist
341
- company.memoize :name
342
- assert_raises(Memoist::AlreadyMemoizedError) { company.memoize :name }
343
- end
344
-
345
502
  def test_double_memoization_with_identifier
346
- Person.memoize :name, :identifier => :again
503
+ # Person memoize :age, :is_developer?, :memoize_protected_test, :name, :name?, :sleep, :update, :update_attributes
504
+ # Student < Person memoize :name, :identifier => :student
505
+ # Teacher < Person memoize :seniority
506
+
507
+ Person.memoize :name, identifier: :again
508
+ p = Person.new
509
+ assert_equal 'Josh', p.name
510
+ assert p.instance_variable_get(:@_memoized_again_name)
511
+
512
+ # HACK: tl;dr: Don't memoize classes in test that are used elsewhere.
513
+ # Calling Person.memoize :name, :identifier => :again pollutes Person
514
+ # and descendents since we cache the memoized method structures.
515
+ # This populates those structs, verifies Person is polluted, resets the
516
+ # structs, cleans up cached memoized_methods
517
+ Student.all_memoized_structs
518
+ Person.all_memoized_structs
519
+ Teacher.all_memoized_structs
520
+ assert Person.memoized_methods.any? { |m| m.ivar == '@_memoized_again_name' }
521
+
522
+ [Student, Teacher, Person].each(&:clear_structs)
523
+ assert Person.memoized_methods.reject! { |m| m.ivar == '@_memoized_again_name' }
524
+ assert_nil Student.memoized_methods.reject! { |m| m.ivar == '@_memoized_again_name' }
525
+ assert_nil Teacher.memoized_methods.reject! { |m| m.ivar == '@_memoized_again_name' }
347
526
  end
348
527
 
349
528
  def test_memoization_with_a_subclass
@@ -356,7 +535,9 @@ class MemoistTest < Minitest::Unit::TestCase
356
535
 
357
536
  def test_memoization_is_chainable
358
537
  klass = Class.new do
359
- def foo; "bar"; end
538
+ def foo
539
+ 'bar'
540
+ end
360
541
  end
361
542
  klass.extend Memoist
362
543
  chainable = klass.memoize :foo
@@ -367,17 +548,16 @@ class MemoistTest < Minitest::Unit::TestCase
367
548
  person = Person.new
368
549
 
369
550
  assert_raises(NoMethodError) { person.memoize_protected_test }
370
- assert_equal "protected", person.send(:memoize_protected_test)
551
+ assert_equal 'protected', person.send(:memoize_protected_test)
371
552
  end
372
553
 
373
554
  def test_private_method_memoization
374
555
  person = Person.new
375
556
 
376
557
  assert_raises(NoMethodError) { person.is_developer? }
377
- assert_equal "Yes", person.send(:is_developer?)
558
+ assert_equal 'Yes', person.send(:is_developer?)
378
559
  assert_equal 1, person.is_developer_calls
379
- assert_equal "Yes", person.send(:is_developer?)
560
+ assert_equal 'Yes', person.send(:is_developer?)
380
561
  assert_equal 1, person.is_developer_calls
381
562
  end
382
-
383
563
  end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  require 'minitest/autorun'
2
2
 
3
- $:.unshift File.expand_path(File.dirname(__FILE__)+"/../lib")
3
+ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memoist
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.16.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Peek
@@ -19,22 +19,36 @@ authors:
19
19
  autorequire:
20
20
  bindir: bin
21
21
  cert_chain: []
22
- date: 2014-10-10 00:00:00.000000000 Z
22
+ date: 2019-12-04 00:00:00.000000000 Z
23
23
  dependencies:
24
+ - !ruby/object:Gem::Dependency
25
+ name: benchmark-ips
26
+ requirement: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ type: :development
32
+ prerelease: false
33
+ version_requirements: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
24
38
  - !ruby/object:Gem::Dependency
25
39
  name: bundler
26
40
  requirement: !ruby/object:Gem::Requirement
27
41
  requirements:
28
- - - "~>"
42
+ - - ">="
29
43
  - !ruby/object:Gem::Version
30
- version: '1.5'
44
+ version: '0'
31
45
  type: :development
32
46
  prerelease: false
33
47
  version_requirements: !ruby/object:Gem::Requirement
34
48
  requirements:
35
- - - "~>"
49
+ - - ">="
36
50
  - !ruby/object:Gem::Version
37
- version: '1.5'
51
+ version: '0'
38
52
  - !ruby/object:Gem::Dependency
39
53
  name: rake
40
54
  requirement: !ruby/object:Gem::Requirement
@@ -55,14 +69,14 @@ dependencies:
55
69
  requirements:
56
70
  - - "~>"
57
71
  - !ruby/object:Gem::Version
58
- version: '3.0'
72
+ version: '5.10'
59
73
  type: :development
60
74
  prerelease: false
61
75
  version_requirements: !ruby/object:Gem::Requirement
62
76
  requirements:
63
77
  - - "~>"
64
78
  - !ruby/object:Gem::Version
65
- version: '3.0'
79
+ version: '5.10'
66
80
  description:
67
81
  email:
68
82
  - josh@joshpeek.com
@@ -83,14 +97,15 @@ extra_rdoc_files: []
83
97
  files:
84
98
  - ".gitignore"
85
99
  - ".travis.yml"
100
+ - CHANGELOG.md
86
101
  - Gemfile
87
102
  - LICENSE.md
88
103
  - README.md
89
104
  - Rakefile
90
105
  - lib/memoist.rb
91
- - lib/memoist/core_ext/singleton_class.rb
92
106
  - lib/memoist/version.rb
93
107
  - memoist.gemspec
108
+ - script/benchmark.rb
94
109
  - test/memoist_test.rb
95
110
  - test/test_helper.rb
96
111
  homepage: https://github.com/matthewrudy/memoist
@@ -105,15 +120,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
120
  requirements:
106
121
  - - ">="
107
122
  - !ruby/object:Gem::Version
108
- version: '0'
123
+ version: 1.9.2
109
124
  required_rubygems_version: !ruby/object:Gem::Requirement
110
125
  requirements:
111
126
  - - ">="
112
127
  - !ruby/object:Gem::Version
113
128
  version: '0'
114
129
  requirements: []
115
- rubyforge_project:
116
- rubygems_version: 2.2.2
130
+ rubygems_version: 3.0.4
117
131
  signing_key:
118
132
  specification_version: 4
119
133
  summary: memoize methods invocation
@@ -1,8 +0,0 @@
1
- module Kernel
2
- # Returns the object's singleton class.
3
- def singleton_class
4
- class << self
5
- self
6
- end
7
- end unless respond_to?(:singleton_class) # exists in 1.9.2
8
- end