def memoize
cache = {}
lambda { |*args|
unless cache.has_key?(args)
cache[args] = self[*args]
end
cache [args]
}
end
factorial = lambda {|x| return 1 if x== 0; x*factorial[x-1];}.memoize
puts factorial.call 10
代码来自“红宝石编程语言”。 但它让我感到困惑:方法(memoize)如何应用于lambda作为其方法? lambda后跟其他lambda用点(。)作为自己的方法吗?
lambda {|x| return 1 if x== 0; x*factorial[x-1];}.memoize
BTW:上面的代码在irb中有效,但是ruby解释器遇到如下错误:
memoize.rb:11: private method `memoize' called for #<Proc:0x0000000103bba018@memoize.rb:11> (NoMethodError)
为什么?
答案 0 :(得分:7)
你在说什么:
def memoize
#...
end
我想你的意思是这样说:
class Proc
def memoize
#...
end
end
这会为Procs添加一个公共memoize
方法,而lambda { ... }
(或者在新Rubies中为-> { ... }
)会为你提供一个Proc实例。
现在转到memoize
本身。方法返回其最后一个表达式的值,对于memoize
,最后一个表达式为:
lambda { |*args|
unless cache.has_key?(args)
cache[args] = self[*args]
end
cache [args]
}
所以memoize
返回Proc(self
)的包装器,它是cache
的闭包,所有这个包装器都是:
cache
是否有相关参数列表的条目(数组args
)。self[*args]
)并将其存储在缓存中。您可以使用[]
方法执行Proc,因此proc.call(a, b)
与proc[a, b]
相同。
答案 1 :(得分:4)
顶层的对象是main,其中定义的任何方法都作为私有实例方法添加到Object
(因此它们随处可用)。
为什么它在irb会话中有效?因为context mode(也是here),默认情况下为 3 。例如,使用值 0 (irb --context-mode 0
),现在它们将像往常一样作为私有方法添加。
如果片段明确定义了哪个类被修改而不是使用隐式顶级,那么最好是教学目的。