memoizable 0.4.1 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 52f96afbe10c6933ec55bedc8651f82d139973ef
4
- data.tar.gz: 5d58b63d4c60c5b36e43b4ff0b54fc85e99bbce7
2
+ SHA256:
3
+ metadata.gz: 9b9efbfc2d856bca857e97e84678b1e49977e2b1f4d0a0d93a239cacea9b95ef
4
+ data.tar.gz: 93a3c69fb399accdc6a8f684c315284c46450af48c5df0d4eb05117af1e2ea2e
5
5
  SHA512:
6
- metadata.gz: f55779f1f1c4a4bcf7414e93ffb3026835effb12c96e5c3551ed03262f7d9f3b876bd96ef36f06412ee16c9e6337b66606199e790903470cf1340161b337b2d9
7
- data.tar.gz: 89f74377d9561f723d17d3cc7d85b5d2c932b3162f47a14f9a10c668d8de1ad9629ecd46ac3bf82782d0e1bd2d225c5ba9c3160187030820ace7f25d5080b518
6
+ metadata.gz: de5d824ac3bd2b23970c50463cc27ba3a83b2f102d0293475edde45b1cebcccb87e5fac3411b6d509ce8866307d8f6eb213b8dc2c81eb17874df162c93329797
7
+ data.tar.gz: 5ae626655e57e079b0a6ea42d9a194e300fc681ec0b3403d1e7c08dea362075a1678041133df583ce296011baaa28da72c1f6e67bab47b067aa633146580658b
data/CHANGELOG.md ADDED
@@ -0,0 +1,100 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.5.0] - 2026-02-09
11
+
12
+ ### Added
13
+
14
+ - `Memory#delete` method to remove a specific memoized value from cache
15
+ - `Memory#clear` method to remove all memoized values from cache
16
+ - `Memory#fetch` now accepts an optional default argument
17
+ - Steep for static type checking
18
+ - Mutant for mutation testing
19
+ - RuboCop and Standard Ruby for linting
20
+ - YARD and Yardstick for documentation coverage
21
+ - GitHub Actions CI pipeline (replacing Travis CI)
22
+ - GitHub Actions workflow for publishing gems to RubyGems with Sigstore attestation
23
+
24
+ ### Changed
25
+
26
+ - Renamed `Memory#[]=` to `Memory#store`
27
+ - `ModuleMethods#memoize` now raises `ArgumentError` when method is already memoized
28
+ - Memoization cache now uses composite keys `[class, method_name]` to support inheritance ([#13](https://github.com/dkubb/memoizable/issues/13))
29
+ - Replaced `thread_safe` gem dependency with Ruby's built-in `Monitor`
30
+
31
+ ### Removed
32
+
33
+ - `Memory#key?` method
34
+ - `ModuleMethods#memoized?` method
35
+ - `ModuleMethods#included` method
36
+ - `thread_safe` gem dependency
37
+
38
+ ## [0.4.2] - 2014-03-27
39
+
40
+ ### Changed
41
+
42
+ - Updated `thread_safe` dependency to use semantic versioning compatible version
43
+
44
+ ## [0.4.1] - 2014-03-04
45
+
46
+ ### Added
47
+
48
+ - Support for Ruby 2.1.0
49
+
50
+ ### Changed
51
+
52
+ - Updated `thread_safe` dependency to ~> 0.2.0
53
+
54
+ ## [0.4.0] - 2013-12-24
55
+
56
+ ### Added
57
+
58
+ - `Memory#marshal_dump` and `Memory#marshal_load` methods for Marshal serialization support ([#10](https://github.com/dkubb/memoizable/issues/10))
59
+
60
+ ## [0.3.1] - 2013-12-18
61
+
62
+ ### Changed
63
+
64
+ - Added double-checked locking to `Memory#fetch` for improved thread safety
65
+
66
+ ### Removed
67
+
68
+ - Unnecessary `Memory#set` method
69
+
70
+ ## [0.3.0] - 2013-12-15
71
+
72
+ ### Added
73
+
74
+ - Thread-safe memory operations using `thread_safe` gem
75
+ - `BlockNotAllowedError` raised when passing a block to memoized methods
76
+ - `ModuleMethods#included` to allow module methods to be memoized
77
+
78
+ ### Changed
79
+
80
+ - Memory is now shallowly frozen after initialization
81
+
82
+ ## [0.2.0] - 2013-11-18
83
+
84
+ ### Added
85
+
86
+ - Core memoization functionality
87
+ - `Memoizable::MethodBuilder` for memoized method creation
88
+ - `InstanceMethods#memoize` to manually set memoized values
89
+ - `InstanceMethods#freeze` support for frozen objects
90
+ - `ModuleMethods#unmemoized_instance_method` to access original method
91
+ - Thread-safe cache using `ThreadSafe::Cache`
92
+
93
+ [Unreleased]: https://github.com/dkubb/memoizable/compare/v0.5.0...HEAD
94
+ [0.5.0]: https://github.com/dkubb/memoizable/compare/v0.4.2...v0.5.0
95
+ [0.4.2]: https://github.com/dkubb/memoizable/compare/v0.4.1...v0.4.2
96
+ [0.4.1]: https://github.com/dkubb/memoizable/compare/v0.4.0...v0.4.1
97
+ [0.4.0]: https://github.com/dkubb/memoizable/compare/v0.3.1...v0.4.0
98
+ [0.3.1]: https://github.com/dkubb/memoizable/compare/v0.3.0...v0.3.1
99
+ [0.3.0]: https://github.com/dkubb/memoizable/compare/v0.2.0...v0.3.0
100
+ [0.2.0]: https://github.com/dkubb/memoizable/compare/v0.0.0...v0.2.0
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Dan Kubb, Erik Michaels-Ober
1
+ Copyright (c) 2013-2026 Dan Kubb, Erik Berlin
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,19 +1,25 @@
1
1
  # Memoizable
2
2
 
3
3
  [![Gem Version](http://img.shields.io/gem/v/memoizable.svg)][gem]
4
- [![Build Status](http://img.shields.io/travis/dkubb/memoizable.svg)][travis]
5
- [![Dependency Status](http://img.shields.io/gemnasium/dkubb/memoizable.svg)][gemnasium]
6
- [![Code Climate](http://img.shields.io/codeclimate/github/dkubb/memoizable.svg)][codeclimate]
7
- [![Coverage Status](http://img.shields.io/coveralls/dkubb/memoizable.svg)][coveralls]
4
+ [![Test](https://github.com/dkubb/memoizable/actions/workflows/test.yml/badge.svg)][test]
5
+ [![Lint](https://github.com/dkubb/memoizable/actions/workflows/lint.yml/badge.svg)][lint]
6
+ [![Mutant](https://github.com/dkubb/memoizable/actions/workflows/mutant.yml/badge.svg)][mutant]
7
+ [![Docs](https://github.com/dkubb/memoizable/actions/workflows/docs.yml/badge.svg)][docs]
8
+ [![Steep](https://github.com/dkubb/memoizable/actions/workflows/steep.yml/badge.svg)][steep]
8
9
 
9
10
  [gem]: https://rubygems.org/gems/memoizable
10
- [travis]: https://travis-ci.org/dkubb/memoizable
11
- [gemnasium]: https://gemnasium.com/dkubb/memoizable
12
- [codeclimate]: https://codeclimate.com/github/dkubb/memoizable
13
- [coveralls]: https://coveralls.io/r/dkubb/memoizable
11
+ [test]: https://github.com/dkubb/memoizable/actions/workflows/test.yml
12
+ [lint]: https://github.com/dkubb/memoizable/actions/workflows/lint.yml
13
+ [mutant]: https://github.com/dkubb/memoizable/actions/workflows/mutant.yml
14
+ [docs]: https://github.com/dkubb/memoizable/actions/workflows/docs.yml
15
+ [steep]: https://github.com/dkubb/memoizable/actions/workflows/steep.yml
14
16
 
15
17
  Memoize method return values
16
18
 
19
+ ## Changelog
20
+
21
+ See [CHANGELOG.md](CHANGELOG.md) for details.
22
+
17
23
  ## Contributing
18
24
 
19
25
  See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
@@ -76,36 +82,15 @@ result. Please keep this in mind when considering which methods to memoize.
76
82
  Supported Ruby Versions
77
83
  -----------------------
78
84
 
79
- This library aims to support and is [tested against][travis] the following Ruby
80
- implementations:
81
-
82
- * Ruby 1.8.7
83
- * Ruby 1.9.2
84
- * Ruby 1.9.3
85
- * Ruby 2.0.0
86
- * Ruby 2.1.0
87
- * [JRuby][]
88
- * [Rubinius][]
89
- * [Ruby Enterprise Edition][ree]
85
+ This library aims to support and is tested against the following Ruby versions:
90
86
 
91
- [jruby]: http://jruby.org/
92
- [rubinius]: http://rubini.us/
93
- [ree]: http://www.rubyenterpriseedition.com/
87
+ * Ruby 3.2
88
+ * Ruby 3.3
89
+ * Ruby 3.4
90
+ * Ruby 4.0
94
91
 
95
92
  If something doesn't work on one of these versions, it's a bug.
96
93
 
97
- This library may inadvertently work (or seem to work) on other Ruby versions or
98
- implementations, however support will only be provided for the implementations
99
- listed above.
100
-
101
- If you would like this library to support another Ruby version or
102
- implementation, you may volunteer to be a maintainer. Being a maintainer
103
- entails making sure all tests run and pass on that implementation. When
104
- something breaks on your implementation, you will be responsible for providing
105
- patches in a timely fashion. If critical issues for a particular implementation
106
- exist at the time of a major release, support for that Ruby version may be
107
- dropped.
108
-
109
94
  ## Copyright
110
95
 
111
- Copyright © 2013 Dan Kubb, Erik Michaels-Ober. See LICENSE for details.
96
+ Copyright © 2013-2026 Dan Kubb, Erik Berlin. See LICENSE for details.
@@ -1,10 +1,8 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Memoizable
4
-
5
4
  # Methods mixed in to memoizable instances
6
5
  module InstanceMethods
7
-
8
6
  # Freeze the object
9
7
  #
10
8
  # @example
@@ -14,7 +12,7 @@ module Memoizable
14
12
  #
15
13
  # @api public
16
14
  def freeze
17
- memoized_method_cache # initialize method cache
15
+ memoized_method_cache # initialize method cache
18
16
  super
19
17
  end
20
18
 
@@ -30,11 +28,11 @@ module Memoizable
30
28
  #
31
29
  # @api public
32
30
  def memoize(data)
33
- data.each { |name, value| memoized_method_cache[name] = value }
31
+ data.each { |name, value| memoized_method_cache.store([self.class, name], value) }
34
32
  self
35
33
  end
36
34
 
37
- private
35
+ private
38
36
 
39
37
  # The memoized method results
40
38
  #
@@ -42,8 +40,7 @@ module Memoizable
42
40
  #
43
41
  # @api private
44
42
  def memoized_method_cache
45
- @_memoized_method_cache ||= Memory.new
43
+ @_memoized_method_cache ||= Memory.new({}) # rubocop:disable Naming/MemoizedInstanceVariableName
46
44
  end
47
-
48
- end # InstanceMethods
49
- end # Memoizable
45
+ end
46
+ end
@@ -1,94 +1,169 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Memoizable
4
-
5
4
  # Storage for memoized methods
6
5
  class Memory
7
-
8
6
  # Initialize the memory storage for memoized methods
9
7
  #
10
- # @param [ThreadSafe::Cache] memory
8
+ # @param [Hash] memory
11
9
  #
12
10
  # @return [undefined]
13
11
  #
14
12
  # @api private
15
- def initialize
16
- @memory = ThreadSafe::Cache.new
13
+ def initialize(memory)
14
+ @memory = memory
17
15
  @monitor = Monitor.new
18
16
  freeze
19
17
  end
20
18
 
21
19
  # Get the value from memory
22
20
  #
21
+ # @example
22
+ #
23
+ # memory = Memoizable::Memory.new(foo: 1)
24
+ # memory[:foo] # => 1
25
+ #
23
26
  # @param [Symbol] name
24
27
  #
25
28
  # @return [Object]
26
29
  #
27
30
  # @api public
28
31
  def [](name)
29
- @memory.fetch(name) do
30
- fail NameError, "No method #{name} is memoized"
32
+ fetch(name) do
33
+ raise NameError, "No method #{name} is memoized"
31
34
  end
32
35
  end
33
36
 
34
37
  # Store the value in memory
35
38
  #
39
+ # @example
40
+ # memory = Memoizable::Memory.new(foo: 1)
41
+ # memory.store(:foo, 2)
42
+ # memory[:foo] # => 2
43
+ #
36
44
  # @param [Symbol] name
37
45
  # @param [Object] value
38
46
  #
39
47
  # @return [undefined]
40
48
  #
41
49
  # @api public
42
- def []=(name, value)
43
- memoized = true
44
- @memory.compute_if_absent(name) do
45
- memoized = false
46
- value
50
+ def store(name, value)
51
+ @monitor.synchronize do
52
+ raise ArgumentError, "The method #{name} is already memoized" if @memory.key?(name)
53
+
54
+ @memory[name] = value
47
55
  end
48
- fail ArgumentError, "The method #{name} is already memoized" if memoized
49
56
  end
50
57
 
51
58
  # Fetch the value from memory, or store it if it does not exist
52
59
  #
60
+ # @example
61
+ # memory = Memoizable::Memory.new(foo: 1)
62
+ # memory.fetch(:foo) { 2 } # => 1
63
+ # memory.fetch(:bar) { 2 } # => 2
64
+ # memory[:bar] # => 2
65
+ # memory.fetch(:baz, 3) # => 3
66
+ #
53
67
  # @param [Symbol] name
68
+ # @param [Object] default
69
+ # optional default value to return if the key is not found
54
70
  #
55
71
  # @yieldreturn [Object]
56
72
  # the value to memoize
57
73
  #
74
+ # @return [Object]
75
+ #
58
76
  # @api public
59
- def fetch(name)
77
+ def fetch(name, default = (no_default = true), &block)
60
78
  @memory.fetch(name) do # check for the key
61
79
  @monitor.synchronize do # acquire a lock if the key is not found
62
80
  @memory.fetch(name) do # recheck under lock
63
- self[name] = yield # set the value
81
+ @memory[name] = resolve_fetch_value(name, no_default, default, &block)
64
82
  end
65
83
  end
66
84
  end
67
85
  end
68
86
 
69
- # Test if the name has a value in memory
87
+ private
88
+
89
+ # Resolve the value for a fetch operation
70
90
  #
71
91
  # @param [Symbol] name
92
+ # @param [Boolean] no_default
93
+ # @param [Object] default
72
94
  #
73
- # @return [Boolean]
95
+ # @yieldreturn [Object]
96
+ #
97
+ # @return [Object]
98
+ #
99
+ # @api private
100
+ def resolve_fetch_value(name, no_default, default)
101
+ if block_given?
102
+ yield
103
+ elsif no_default
104
+ raise KeyError, "key not found: #{name.inspect}"
105
+ else
106
+ default
107
+ end
108
+ end
109
+
110
+ public
111
+
112
+ # Remove a specific value from memory
113
+ #
114
+ # @example
115
+ # memory = Memoizable::Memory.new(foo: 1)
116
+ # memory.delete(:foo)
117
+ #
118
+ # @param [Symbol] name
119
+ #
120
+ # @return [Object]
74
121
  #
75
122
  # @api public
76
- def key?(name)
77
- @memory.key?(name)
123
+ def delete(name)
124
+ @monitor.synchronize do
125
+ @memory.delete(name)
126
+ end
127
+ end
128
+
129
+ # Remove all values from memory
130
+ #
131
+ # @example
132
+ # memory = Memoizable::Memory.new(foo: 1)
133
+ # memory.clear # => memory
134
+ #
135
+ # @return [self]
136
+ #
137
+ # @api public
138
+ def clear
139
+ @monitor.synchronize do
140
+ @memory.clear
141
+ end
142
+ self
78
143
  end
79
144
 
80
145
  # A hook that allows Marshal to dump the object
81
146
  #
147
+ # @example
148
+ # memory = Memoizable::Memory.new(foo: 1)
149
+ # Marshal.dump(memory)
150
+ # # => "\x04\bU:\x17Memoizable::Memory{\x06:\bfooi\x06"
151
+ #
82
152
  # @return [Hash]
83
153
  # A hash used to populate the internal memory
84
154
  #
85
155
  # @api public
86
156
  def marshal_dump
87
- @memory.marshal_dump
157
+ @memory
88
158
  end
89
159
 
90
160
  # A hook that allows Marshal to load the object
91
161
  #
162
+ # @example
163
+ # memory = Memoizable::Memory.new(foo: 1)
164
+ # Marshal.load(Marshal.dump(memory))
165
+ # # => #<Memoizable::Memory:0x007f9c2a8b6b20 @memory={:foo=>1}>
166
+ #
92
167
  # @param [Hash] hash
93
168
  # A hash used to populate the internal memory
94
169
  #
@@ -96,9 +171,7 @@ module Memoizable
96
171
  #
97
172
  # @api public
98
173
  def marshal_load(hash)
99
- initialize
100
- @memory.marshal_load(hash)
174
+ initialize(hash)
101
175
  end
102
-
103
- end # Memory
104
- end # Memoizable
176
+ end
177
+ end
@@ -1,13 +1,10 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Memoizable
4
-
5
4
  # Build the memoized method
6
5
  class MethodBuilder
7
-
8
6
  # Raised when the method arity is invalid
9
7
  class InvalidArityError < ArgumentError
10
-
11
8
  # Initialize an invalid arity exception
12
9
  #
13
10
  # @param [Module] descendant
@@ -18,12 +15,10 @@ module Memoizable
18
15
  def initialize(descendant, method, arity)
19
16
  super("Cannot memoize #{descendant}##{method}, its arity is #{arity}")
20
17
  end
21
-
22
- end # InvalidArityError
18
+ end
23
19
 
24
20
  # Raised when a block is passed to a memoized method
25
21
  class BlockNotAllowedError < ArgumentError
26
-
27
22
  # Initialize a block not allowed exception
28
23
  #
29
24
  # @param [Module] descendant
@@ -33,11 +28,13 @@ module Memoizable
33
28
  def initialize(descendant, method)
34
29
  super("Cannot pass a block to #{descendant}##{method}, it is memoized")
35
30
  end
36
-
37
- end # BlockNotAllowedError
31
+ end
38
32
 
39
33
  # The original method before memoization
40
34
  #
35
+ # @example
36
+ # method_builder.original_method # => :foo
37
+ #
41
38
  # @return [UnboundMethod]
42
39
  #
43
40
  # @api public
@@ -53,12 +50,12 @@ module Memoizable
53
50
  #
54
51
  # @api private
55
52
  def initialize(descendant, method_name, freezer)
56
- @descendant = descendant
57
- @method_name = method_name
58
- @freezer = freezer
53
+ @descendant = descendant
54
+ @method_name = method_name
55
+ @freezer = freezer
59
56
  @original_visibility = visibility
60
- @original_method = @descendant.instance_method(@method_name)
61
- assert_arity(@original_method.arity)
57
+ @original_method = descendant.instance_method(@method_name)
58
+ assert_arity(original_method.arity)
62
59
  end
63
60
 
64
61
  # Build a new memoized method
@@ -76,7 +73,7 @@ module Memoizable
76
73
  self
77
74
  end
78
75
 
79
- private
76
+ private
80
77
 
81
78
  # Assert the method arity is zero
82
79
  #
@@ -88,9 +85,9 @@ module Memoizable
88
85
  #
89
86
  # @api private
90
87
  def assert_arity(arity)
91
- if arity.nonzero?
92
- fail InvalidArityError.new(@descendant, @method_name, arity)
93
- end
88
+ return unless arity.nonzero?
89
+
90
+ raise InvalidArityError.new(@descendant, @method_name, arity)
94
91
  end
95
92
 
96
93
  # Remove the original method
@@ -109,13 +106,15 @@ module Memoizable
109
106
  #
110
107
  # @api private
111
108
  def create_memoized_method
112
- name, method, freezer = @method_name, @original_method, @freezer
113
- @descendant.module_eval do
114
- define_method(name) do |&block|
115
- fail BlockNotAllowedError.new(self.class, name) if block
116
- memoized_method_cache.fetch(name) do
117
- freezer.call(method.bind(self).call)
118
- end
109
+ name = @method_name
110
+ method = @original_method
111
+ freezer = @freezer
112
+ descendant = @descendant
113
+ @descendant.define_method(name) do |&block|
114
+ raise BlockNotAllowedError.new(self.class, name) if block # steep:ignore NoMethod
115
+
116
+ memoized_method_cache.fetch([descendant, name]) do # steep:ignore NoMethod
117
+ freezer.call(method.bind_call(self))
119
118
  end
120
119
  end
121
120
  end
@@ -126,7 +125,7 @@ module Memoizable
126
125
  #
127
126
  # @api private
128
127
  def set_method_visibility
129
- @descendant.send(@original_visibility, @method_name)
128
+ @descendant.__send__(@original_visibility, @method_name)
130
129
  end
131
130
 
132
131
  # Get the visibility of the original method
@@ -135,11 +134,10 @@ module Memoizable
135
134
  #
136
135
  # @api private
137
136
  def visibility
138
- if @descendant.private_method_defined?(@method_name) then :private
137
+ if @descendant.private_method_defined?(@method_name) then :private
139
138
  elsif @descendant.protected_method_defined?(@method_name) then :protected
140
- else :public
139
+ else :public
141
140
  end
142
141
  end
143
-
144
- end # MethodBuilder
145
- end # Memoizable
142
+ end
143
+ end
@@ -1,9 +1,9 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Memoizable
4
-
5
4
  # Methods mixed in to memoizable singleton classes
6
5
  module ModuleMethods
6
+ include Memoizable
7
7
 
8
8
  # Return default deep freezer
9
9
  #
@@ -26,34 +26,10 @@ module Memoizable
26
26
  #
27
27
  # @api public
28
28
  def memoize(*methods)
29
- methods.each(&method(:memoize_method))
29
+ methods.each { |method| memoize_method(method) }
30
30
  self
31
31
  end
32
32
 
33
- # Test if an instance method is memoized
34
- #
35
- # @example
36
- # class Foo
37
- # include Memoizable
38
- #
39
- # def bar
40
- # end
41
- # memoize :bar
42
- # end
43
- #
44
- # Foo.memoized?(:bar) # true
45
- # Foo.memoized?(:baz) # false
46
- #
47
- # @param [Symbol] name
48
- #
49
- # @return [Boolean]
50
- # true if method is memoized, false if not
51
- #
52
- # @api private
53
- def memoized?(name)
54
- memoized_methods.key?(name)
55
- end
56
-
57
33
  # Return unmemoized instance method
58
34
  #
59
35
  # @example
@@ -81,20 +57,7 @@ module Memoizable
81
57
  memoized_methods[name].original_method
82
58
  end
83
59
 
84
- private
85
-
86
- # Hook called when module is included
87
- #
88
- # @param [Module] descendant
89
- # the module including ModuleMethods
90
- #
91
- # @return [self]
92
- #
93
- # @api private
94
- def included(descendant)
95
- super
96
- descendant.module_eval { include Memoizable }
97
- end
60
+ private
98
61
 
99
62
  # Memoize the named method
100
63
  #
@@ -105,6 +68,8 @@ module Memoizable
105
68
  #
106
69
  # @api private
107
70
  def memoize_method(method_name)
71
+ raise ArgumentError, "The method #{method_name} is already memoized" if memoized_methods.key?(method_name)
72
+
108
73
  memoized_methods[method_name] = MethodBuilder.new(
109
74
  self,
110
75
  method_name,
@@ -118,8 +83,7 @@ module Memoizable
118
83
  #
119
84
  # @api private
120
85
  def memoized_methods
121
- @_memoized_methods ||= Memory.new
86
+ @memoized_methods ||= {}
122
87
  end
123
-
124
- end # ModuleMethods
125
- end # Memoizable
88
+ end
89
+ end
@@ -1,8 +1,6 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Memoizable
4
-
5
4
  # Gem version
6
- VERSION = '0.4.1'.freeze
7
-
8
- end # Memoizable
5
+ VERSION = "0.5.0"
6
+ end