module AdLint::Memoizable
Public Instance Methods
memoize(name, *opts)
click to toggle source
# File lib/adlint/memo.rb, line 35 def memoize(name, *opts) force_nullary, key_indices = extract_memoize_options(opts) case when instance_method(name).arity == 0 || force_nullary memoize_nullary_method(name) when instance_method(name).arity == 1 || key_indices.size == 1 memoize_unary_method(name, key_indices.first || 0) else memoize_polynomial_method(name, key_indices) end end
Private Instance Methods
cache_name_of(name)
click to toggle source
# File lib/adlint/memo.rb, line 202 def cache_name_of(name) "@__cache_of__#{name.to_s.sub("?", "_p")}" end
define_key_generator(name, key_indices)
click to toggle source
# File lib/adlint/memo.rb, line 178 def define_key_generator(name, key_indices) if key_indices.empty? class_eval <<-EOS define_method(:__key_for_#{name}) do |*args| args end EOS else class_eval <<-EOS define_method(:__key_for_#{name}) do |*args| args.values_at(#{key_indices.join(',')}) end EOS end class_eval "private(:__key_for_#{name})" end
extract_memoize_options(opts)
click to toggle source
# File lib/adlint/memo.rb, line 48 def extract_memoize_options(opts) hash = opts.first || {} [hash[:force_nullary], hash[:key_indices] || []] end
memoize_nullary_method(name)
click to toggle source
# File lib/adlint/memo.rb, line 53 def memoize_nullary_method(name) save_memoizing_method(name) prepare_nullary_method_cache(name) class_eval <<-EOS define_method(:#{name}) do |*args| if #{cache_name_of(name)}_initialized ||= false #{cache_name_of(name)}_forbidden = false #{cache_name_of(name)} else if #{cache_name_of(name)}_forbidden ||= false #{cache_name_of(name)}_forbidden = false #{orig_name_of(name)} else #{cache_name_of(name)}_initialized = true #{cache_name_of(name)} = #{orig_name_of(name)}(*args) end end end EOS end
memoize_polynomial_method(name, key_indices)
click to toggle source
# File lib/adlint/memo.rb, line 101 def memoize_polynomial_method(name, key_indices) save_memoizing_method(name) prepare_polynomial_method_cache(name, key_indices) class_eval <<-EOS define_method(:#{name}) do |*args| key = __key_for_#{name}(*args) if #{cache_name_of(name)}_initialized ||= false #{cache_name_of(name)}_forbidden = false if #{cache_name_of(name)}.include?(key) #{cache_name_of(name)}[key] else #{cache_name_of(name)}[key] = #{orig_name_of(name)}(*args) end else if #{cache_name_of(name)}_forbidden ||= false #{cache_name_of(name)}_forbidden = false #{orig_name_of(name)}(*args) else #{cache_name_of(name)}_initialized = true #{cache_name_of(name)} = {} #{cache_name_of(name)}[key] = #{orig_name_of(name)}(*args) end end end EOS end
memoize_unary_method(name, key_index)
click to toggle source
# File lib/adlint/memo.rb, line 74 def memoize_unary_method(name, key_index) save_memoizing_method(name) prepare_unary_method_cache(name, key_index) class_eval <<-EOS define_method(:#{name}) do |*args| key = args[#{key_index}] if #{cache_name_of(name)}_initialized ||= false #{cache_name_of(name)}_forbidden = false if #{cache_name_of(name)}.include?(key) #{cache_name_of(name)}[key] else #{cache_name_of(name)}[key] = #{orig_name_of(name)}(*args) end else if #{cache_name_of(name)}_forbidden ||= false #{cache_name_of(name)}_forbidden = false #{orig_name_of(name)}(*args) else #{cache_name_of(name)}_initialized = true #{cache_name_of(name)} = {} #{cache_name_of(name)}[key] = #{orig_name_of(name)}(*args) end end end EOS end
orig_name_of(name)
click to toggle source
# File lib/adlint/memo.rb, line 206 def orig_name_of(name) "__orig_#{name}" end
prepare_nullary_method_cache(name)
click to toggle source
# File lib/adlint/memo.rb, line 128 def prepare_nullary_method_cache(name) class_eval <<-EOS define_method(:forbid_once_memo_of__#{name}) do #{cache_name_of(name)}_forbidden = true end define_method(:clear_memo_of__#{name}) do #{cache_name_of(name)} = nil #{cache_name_of(name)}_initialized = false end define_method(:forget_memo_of__#{name}) do clear_memo_of__#{name} end EOS end
prepare_polynomial_method_cache(name, key_indices)
click to toggle source
# File lib/adlint/memo.rb, line 160 def prepare_polynomial_method_cache(name, key_indices) define_key_generator(name, key_indices) class_eval <<-EOS define_method(:forbid_once_memo_of__#{name}) do #{cache_name_of(name)}_forbidden = true end define_method(:clear_memo_of__#{name}) do #{cache_name_of(name)} = nil #{cache_name_of(name)}_initialized = false end define_method(:forget_memo_of__#{name}) do |*args| if #{cache_name_of(name)}_initialized #{cache_name_of(name)}.delete(__key_for_#{name}(*args)) end end EOS end
prepare_unary_method_cache(name, key_index)
click to toggle source
# File lib/adlint/memo.rb, line 143 def prepare_unary_method_cache(name, key_index) class_eval <<-EOS define_method(:forbid_once_memo_of__#{name}) do #{cache_name_of(name)}_forbidden = true end define_method(:clear_memo_of__#{name}) do #{cache_name_of(name)} = nil #{cache_name_of(name)}_initialized = false end define_method(:forget_memo_of__#{name}) do |*args| if #{cache_name_of(name)}_initialized #{cache_name_of(name)}.delete(args[#{key_index}]) end end EOS end
save_memoizing_method(name)
click to toggle source
# File lib/adlint/memo.rb, line 195 def save_memoizing_method(name) class_eval <<-EOS alias_method(:#{orig_name_of(name)}, :#{name}) private(:#{orig_name_of(name)}) EOS end