如何在Ruby中通常记忆任何函数?

Era*_*nes 2 ruby memoization

我正在尝试编写一个函数来统一memoize Ruby中的任何函数(如本文第6页所述,它在Python中做同样的事情:http://courses.csail.mit.edu/6.01/spring07/lectures/讲座.pdf),但我卡住了.这是我的代码,它不起作用(函数被正确评估,但没有被记忆).谁能告诉我哪里出错了?

def fib(n)
  return n if n<2
  fib(n-1) + fib(n-2)
end

def memoize(&f)
  memo = {}
  doit = ->(arg) do
    return memo[arg] if memo[arg] 
    memo[arg] = f.call(arg)
    memo[arg]
  end
  doit
end

fib = memoize{|x| fib(x)}
puts fib.call(50)
Run Code Online (Sandbox Code Playgroud)

Ser*_*sev 6

fib以递归方式调用自身,并通过这样做完全绕过您的memoization逻辑.无论选择哪种方法,都必须覆盖原始定义fib,以便对其进行包装记忆.

@Aetherus给出了一个有效的答案.这是一个更动态的解决方案:

def fib(n)
  return n if n<2
  fib(n-1) + fib(n-2)
end

def memoize(method_name)
  memo = {}
  old_fib = method(method_name)
  define_method(method_name) do |arg|
    return memo[arg] if memo[arg] 
    memo[arg] = old_fib.call(arg)
    memo[arg]
  end
end

memoize(:fib)

puts fib(50)
Run Code Online (Sandbox Code Playgroud)