在下面的示例中,我原以为close_over_me
可以通过闭包对返回的对象使用。
但显然事实并非如此。
为什么不呢?
此外,有哪些选项可以使代码按预期工作(即返回值1而不是错误)?
def test_closure(close_over_me: 1)
Object.new.tap do |x|
def x.captured_var
close_over_me
end
end
end
o = test_closure
o.captured_var # NameError: undefined local variable or method `close_over_me' for #<Object:0x007fb46b41a718>
答案 0 :(得分:5)
原因是def
关键字定义了一个新范围。
要解决此问题,您可以改为使用Object#define_singleton_method
:
def test_closure(close_over_me: 1)
Object.new.tap do |x|
x.define_singleton_method(:captured_var) do
close_over_me
end
end
end
o = test_closure
o.captured_var # => 1
答案 1 :(得分:3)
这就是所谓的“范围门”。关键字def
/ class
/ module
将所有局部变量推出范围。
如果没有这些,你必须想出一种修补方法。