class Module

def memoize_function(*function_ids)

function.
memoized result does ONLY depend on the arguments given to the
Automatically memoize calls of the functions +function_ids+. The
def memoize_function(*function_ids)
  function_ids.extend(ExtractLastArgumentOptions)
  function_ids, opts = function_ids.extract_last_argument_options
  mc = __memoize_cache__
  function_ids.each do |function_id|
    function_id = function_id.to_s.to_sym
    memoize_apply_visibility function_id do
      orig_function = instance_method(function_id)
      __send__(:define_method, function_id) do |*args|
        if mc.key?(function_id) and result = mc[function_id][args]
          result
        else
          (mc[function_id] ||= {})[args] = result = orig_function.bind(self).call(*args)
          opts[:freeze] and result.freeze
          $DEBUG and warn "#{self.class} cached function #{function_id}(#{args.inspect unless args.empty?}) = #{result.inspect}"
        end
        result
      end
    end
  end
  function_ids.size == 1 ? function_ids.first : function_ids
end