Module: Memist::ClassMethods

Defined in:
lib/memist/class_methods.rb

Instance Method Summary collapse

Instance Method Details

#memoization_dependenciesObject



38
39
40
# File 'lib/memist/class_methods.rb', line 38

def memoization_dependencies
  @memoization_dependencies ||= {}
end

#memoize(method, options = {}) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/memist/class_methods.rb', line 3

def memoize(method, options = {})
  if instance_method(method).arity > 1
    raise ArgumentError, "Cannot memoize `#{method}` method because it accepts more than one argument."
  end

  if options[:depends_on].is_a?(Array)
    options[:depends_on].each do |other_method|
      memoization_dependencies[method.to_sym] ||= []
      memoization_dependencies[method.to_sym] << other_method.to_sym
    end
  end

  define_method "#{method}_with_memoization" do |arg = nil|
    if memoize?
      @memoized_values ||= Hash.new { |hash, key| hash[key] = {} }
      if @memoized_values.key?(method) && @memoized_values[method].key?(arg)
        @memoized_values[method][arg]
      else
        value = send("#{method}_without_memoization", *arg)
        @memoized_values[method][arg] = value
      end
    else
      send("#{method}_without_memoization", *arg)
    end
  end

  define_method "#{method}!" do |arg = nil|
    flush_memoization(method, arg)
    send("#{method}_with_memoization", *arg)
  end

  alias_method "#{method}_without_memoization", method
  alias_method method, "#{method}_with_memoization"
end