Sha256: 7eca84a64e920aaef5478deb21f360702d71c2a42975c3636a61a73358ae1ed4

Contents?: true

Size: 1.88 KB

Versions: 2

Compression:

Stored size: 1.88 KB

Contents

require 'memoized/parameters'

module Memoized
  class CannotMemoize < ::StandardError; end

  def self.included(base)
    base.extend ClassMethods
    base.send :include, InstanceMethods
  end

  def self.safe_name(method_name)
    method_name.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang').to_sym
  end

  def self.ivar_name(method_name)
    :"@_memoized_#{self.safe_name(method_name)}"
  end

  module ClassMethods
    def memoize(*method_names)
      method_names.each do |method_name|
        memoized_ivar_name = Memoized.ivar_name(method_name)
        unmemoized_method = "_unmemoized_#{method_name}"

        alias_method unmemoized_method, method_name

        parameters = Parameters.new(instance_method(unmemoized_method).parameters)

        module_eval(<<-RUBY)
          def #{method_name}(#{parameters.signature})
            #{parameters.cache_key}

            #{memoized_ivar_name} ||= {}
            
            if #{memoized_ivar_name}.key?(cache_key)
              #{memoized_ivar_name}[cache_key]
            else
              live_result = if all_kwargs.empty?
                #{unmemoized_method}(*all_args)
              else  
                #{unmemoized_method}(*all_args, **all_kwargs)
              end
              #{memoized_ivar_name}[cache_key] = live_result
              live_result
            end
          end
        RUBY

        if self.private_method_defined?(unmemoized_method)
          private method_name
        elsif self.protected_method_defined?(unmemoized_method)
          protected method_name
        end
      end
    end
  end

  module InstanceMethods
    def unmemoize(method_name)
      self.instance_variable_set(Memoized.ivar_name(method_name), nil)
    end

    def unmemoize_all
      (methods + private_methods + protected_methods).each do |method|
        if method.to_s =~ /^_unmemoized_(.*)/
          unmemoize($1)
        end
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
memoized-1.1.2 lib/memoized.rb
memoized-1.1.1 lib/memoized.rb