diff --git a/lib/memo_wise.rb b/lib/memo_wise.rb index e713744f..07388ca0 100644 --- a/lib/memo_wise.rb +++ b/lib/memo_wise.rb @@ -200,7 +200,7 @@ def #{method_name} klass.module_eval <<~HEREDOC, __FILE__, __LINE__ + 1 def #{method_name}(#{MemoWise::InternalAPI.args_str(method)}) - _memo_wise_hash = (@_memo_wise[#{index}] ||= {}) + _memo_wise_hash = (#{MemoWise::InternalAPI.method_name_to_sym(klass, method_name)} ||= {}) _memo_wise_output = _memo_wise_hash[#{key}] if _memo_wise_output || _memo_wise_hash.key?(#{key}) _memo_wise_output @@ -226,7 +226,7 @@ def #{method_name}(#{MemoWise::InternalAPI.args_str(method)}) # faster than `Hash#fetch`. klass.module_eval <<~HEREDOC, __FILE__, __LINE__ + 1 def #{method_name}(#{MemoWise::InternalAPI.args_str(method)}) - _memo_wise_hash = (@_memo_wise[#{index}] ||= {}) + _memo_wise_hash = (#{MemoWise::InternalAPI.method_name_to_sym(klass, method_name)} ||= {}) _memo_wise_key = #{MemoWise::InternalAPI.key_str(method)} _memo_wise_output = _memo_wise_hash[_memo_wise_key] if _memo_wise_output || _memo_wise_hash.key?(_memo_wise_key) @@ -453,7 +453,7 @@ def preset_memo_wise(method_name, *args, **kwargs) return end - hash = (@_memo_wise[index] ||= {}) + hash = MemoWise::InternalAPI.memo_wise_hash(self, method_name) case method_arguments when MemoWise::InternalAPI::ONE_REQUIRED_POSITIONAL then hash[args.first] = yield @@ -540,8 +540,8 @@ def reset_memo_wise(method_name = nil, *args, **kwargs) raise ArgumentError, "Provided args when method_name = nil" unless args.empty? raise ArgumentError, "Provided kwargs when method_name = nil" unless kwargs.empty? - @_memo_wise.clear - @_memo_wise_sentinels.clear + # Clear any instance variables created by memo_wise + instance_variables.select { _1.to_s.start_with?("@_memo_wise") }.map { eval("#{_1}.clear") } return end @@ -554,6 +554,7 @@ def reset_memo_wise(method_name = nil, *args, **kwargs) method = method(method_name) method_arguments = MemoWise::InternalAPI.method_arguments(method) index = api.index(method_name) + memo_wise_hash = MemoWise::InternalAPI.memo_wise_hash(self, method_name) case method_arguments when MemoWise::InternalAPI::NONE @@ -561,31 +562,31 @@ def reset_memo_wise(method_name = nil, *args, **kwargs) @_memo_wise[index] = nil when MemoWise::InternalAPI::ONE_REQUIRED_POSITIONAL if args.empty? - @_memo_wise[index]&.clear + memo_wise_hash&.clear else - @_memo_wise[index]&.delete(args.first) + memo_wise_hash&.delete(args.first) end when MemoWise::InternalAPI::ONE_REQUIRED_KEYWORD if kwargs.empty? - @_memo_wise[index]&.clear + memo_wise_hash&.clear else - @_memo_wise[index]&.delete(kwargs.first.last) + memo_wise_hash&.delete(kwargs.first.last) end when MemoWise::InternalAPI::SPLAT if args.empty? - @_memo_wise[index]&.clear + memo_wise_hash&.clear else - @_memo_wise[index]&.delete(args) + memo_wise_hash&.delete(args) end when MemoWise::InternalAPI::DOUBLE_SPLAT if kwargs.empty? - @_memo_wise[index]&.clear + memo_wise_hash&.clear else - @_memo_wise[index]&.delete(kwargs) + memo_wise_hash&.delete(kwargs) end else # MemoWise::InternalAPI::MULTIPLE_REQUIRED, MemoWise::InternalAPI::SPLAT_AND_DOUBLE_SPLAT if args.empty? && kwargs.empty? - @_memo_wise[index]&.clear + memo_wise_hash&.clear else key = if method_arguments == MemoWise::InternalAPI::SPLAT_AND_DOUBLE_SPLAT [args, kwargs] @@ -594,7 +595,7 @@ def reset_memo_wise(method_name = nil, *args, **kwargs) type == :req ? args[i] : kwargs[name] # rubocop:disable Metrics/BlockNesting end end - @_memo_wise[index]&.delete(key) + memo_wise_hash&.delete(key) end end end diff --git a/lib/memo_wise/internal_api.rb b/lib/memo_wise/internal_api.rb index 21f0bcae..890ec131 100644 --- a/lib/memo_wise/internal_api.rb +++ b/lib/memo_wise/internal_api.rb @@ -293,6 +293,15 @@ def validate_memo_wised!(method_name) end end + def self.memo_wise_hash(klass, method_name) + klass.instance_variable_get(method_name_to_sym(klass, method_name)) || + klass.instance_variable_set(method_name_to_sym(klass, method_name), {}) + end + + def self.method_name_to_sym(klass, method_name) + "@_memo_wise_#{method_name}".gsub("?", "__q__").to_sym + end + private # @return [Class] where we look for method definitions