为什么使用define_method定义方法时局部变量会丢失其值?
尝试遵循 pragpub 的元编程截屏视频,但由于自截屏视频发布以来 Ruby 发生的变化而遇到了一些问题。
很难在没有代码的情况下解释问题,所以这就是:
class Discounter
def discount(*skus)
expensive_discount_calculation(*skus)
end
private
def expensive_discount_calculation(*skus)
puts "Expensive calculation for #{skus.inspect}"
skus.inject {|m, n| m + n }
end
end
def memoize(obj, method)
ghost = class << obj; self; end
ghost.class_eval do
define_method(method) do |*args|
memory ||= {}
memory.has_key?(args) ? memory[args] : memory[args] = super(*args)
end
end
end
d = Discounter.new
memoize(d, :discount)
puts d.discount(1,2,3)
puts d.discount(1,2,3)
puts d.discount(2,3,4)
puts d.discount(2,3,4)
问题: 方法 memorize 中的局部变量应该仅在传递时更改(通过从 Discounter#discount 获取返回值)与以前不同的论点。
例如,我希望运行上面代码的输出如下所示:
Expensive calculation for [1, 2, 3]
6
6
Expensive calculation for [2, 3, 4]
9
9
但这就是实际输出:
Expensive calculation for [1, 2, 3]
6
Expensive calculation for [1, 2, 3]
6
Expensive calculation for [2, 3, 4]
9
Expensive calculation for [2, 3, 4]
9
为什么局部变量在调用过程中不保留?为了使这段代码正常工作,我缺少什么?
谢谢
Trying to follow along with a metaprogramming screencast from pragpub and ran into some problems because of changes in Ruby since the release of screencast.
Hard to explain the problem w/o the code, so here's that:
class Discounter
def discount(*skus)
expensive_discount_calculation(*skus)
end
private
def expensive_discount_calculation(*skus)
puts "Expensive calculation for #{skus.inspect}"
skus.inject {|m, n| m + n }
end
end
def memoize(obj, method)
ghost = class << obj; self; end
ghost.class_eval do
define_method(method) do |*args|
memory ||= {}
memory.has_key?(args) ? memory[args] : memory[args] = super(*args)
end
end
end
d = Discounter.new
memoize(d, :discount)
puts d.discount(1,2,3)
puts d.discount(1,2,3)
puts d.discount(2,3,4)
puts d.discount(2,3,4)
Problem: The local variable in the method memorize should only change (by taking the return value from Discounter#discount) if it is being passed different arguments than it previously was.
For example I expect the output from running the code above to look like:
Expensive calculation for [1, 2, 3]
6
6
Expensive calculation for [2, 3, 4]
9
9
But this is the actual output:
Expensive calculation for [1, 2, 3]
6
Expensive calculation for [1, 2, 3]
6
Expensive calculation for [2, 3, 4]
9
Expensive calculation for [2, 3, 4]
9
Why isn't the local variable persisting across the calls? What am I missing to make this code work?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果在块内定义局部变量,则到达块末尾时它将消失。
为了实现您想要的生命周期,您需要在块之前定义
memory
变量:If you define a local variable inside a block, it will vanish when the end of the block is reached.
To achieve the lifetime you want, you need to define the
memory
variable before the block: