class Dry::Core::Memoizable::Memoizer
def define_memoizable(method:)
- Api: - private
def define_memoizable(method:) parameters = method.parameters mod = self kernel = KERNEL if parameters.empty? key = "#{__id__}:#{method.name}".hash.abs define_method(method.name) do value = super() if kernel[:frozen].bind_call(self) # It's not possible to modify singleton classes # of frozen objects mod.remove_method(method.name) mod.module_eval(<<~RUBY, __FILE__, __LINE__ + 1) def #{method.name} # def slow_calc cached = @__memoized__[#{key}] # cached = @__memoized__[12345678] # if cached || @__memoized__.key?(#{key}) # if cached || @__memoized__.key?(12345678) cached # cached else # else @__memoized__[#{key}] = super # @__memoized__[12345678] = super end # end end # end RUBY else # We make an attr_reader for computed value. # Readers are "special-cased" in ruby so such # access will be the fastest way, faster than you'd # expect :) attr_name = :"__memozed_#{key}__" ivar_name = :"@#{attr_name}" kernel[:ivar_set].bind_call(self, ivar_name, value) eigenclass = kernel[:singleton].bind_call(self) eigenclass.attr_reader(attr_name) eigenclass.alias_method(method.name, attr_name) eigenclass.remove_method(attr_name) end value end else mapping = parameters.to_h { |k, v = nil| [k, v] } params, binds = declaration(parameters, mapping) last_param = parameters.last if last_param[0].eql?(:block) && !last_param[1].eql?(:&) Deprecations.warn(<<~WARN) Memoization for block-accepting methods isn't safe. Every call creates a new block instance bloating cached results. In the future, blocks will still be allowed but won't participate in cache key calculation. WARN end module_eval(<<~RUBY, __FILE__, __LINE__ + 1) def #{method.name}(#{params.join(", ")}) # def slow_calc(arg1, arg2, arg3) key = [:"#{method.name}", #{binds.join(", ")}].hash # key = [:slow_calc, arg1, arg2, arg3].hash # if @__memoized__.key?(key) # if @__memoized__.key?(key) @__memoized__[key] # @__memoized__[key] else # else @__memoized__[key] = super # @__memoized__[key] = super end # end end # end RUBY end end