module Memery::ClassMethods::MemoizationModule

Constants

Cache

Public Instance Methods

define_memoized_method!(klass, method_name, condition: nil, ttl: nil) click to toggle source
Calls superclass method
# File lib/memery.rb, line 71
def define_memoized_method!(klass, method_name, condition: nil, ttl: nil)
  method_key = "#{method_name}_#{object_id}"

  original_visibility = method_visibility(klass, method_name)
  original_arity = klass.instance_method(method_name).arity

  define_method(method_name) do |*args, &block|
    if block || (condition && !instance_exec(&condition))
      return super(*args, &block)
    end

    cache_store = (@_memery_memoized_values ||= {})
    cache_key = original_arity.zero? ? method_key : [method_key, *args]
    cache = cache_store[cache_key]

    return cache.result if cache&.fresh?(ttl)

    result = super(*args)
    new_cache = Cache.new(result, Memery.monotonic_clock)
    cache_store[cache_key] = new_cache

    result
  end

  ruby2_keywords(method_name)
  send(original_visibility, method_name)
end

Private Instance Methods

method_visibility(klass, method_name) click to toggle source
# File lib/memery.rb, line 101
def method_visibility(klass, method_name)
  if klass.private_method_defined?(method_name)
    :private
  elsif klass.protected_method_defined?(method_name)
    :protected
  elsif klass.public_method_defined?(method_name)
    :public
  else
    raise ArgumentError, "Method #{method_name} is not defined on #{klass}"
  end
end