Module: Mandate::Memoize

Defined in:
lib/mandate/memoize.rb

Instance Method Summary collapse

Instance Method Details

#__mandate_memoize(method_name) ⇒ Object

Create an anonymous module that defines a method with the same name as main method being defined. Add some memoize code to check whether the method has been previously called or not. If it’s not been then call the underlying method and store the result.

We then prepend this module so that its method comes first in the method-lookup chain.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/mandate/memoize.rb', line 30

def __mandate_memoize(method_name)
  # Capture the access level of the method outside the module
  # then set the method inside the module to have the same
  # access later.
  if private_instance_methods.include?(method_name)
    access_modifier = :private
  elsif protected_instance_methods.include?(method_name)
    access_modifier = :protected
  end

  memoizer = Module.new do
    define_method method_name do
      @__mandate_memoized_results ||= {}

      if @__mandate_memoized_results.include?(method_name)
        @__mandate_memoized_results[method_name]
      else
        @__mandate_memoized_results[method_name] = super()
      end
    end

    send(access_modifier, method_name) if access_modifier
  end
  prepend memoizer
end

#memoizeObject

This method is called on the line before a define statement. It puts mandate into memoizing mode



5
6
7
# File 'lib/mandate/memoize.rb', line 5

def memoize
  @__mandate_memoizing = true
end

#method_added(method_name) ⇒ Object

Intercept a method being added. Create the method as normal, then if we are in memoize mode, call out to the memoize function and reset out of memoizing mode.



13
14
15
16
17
18
19
20
# File 'lib/mandate/memoize.rb', line 13

def method_added(method_name)
  super

  return unless instance_variable_defined?("@__mandate_memoizing") && @__mandate_memoizing

  __mandate_memoize(method_name)
  @__mandate_memoizing = false
end