我正在使用Ruiby 1.9.2-p180。以下代码抛出错误:
“test.rb:20:in <main>': undefined local variable or method
val”for main:Object(NameError)“
有没有办法让monkeypatching工作返回val
?
class Test
def m
"m"
end
end
def inject(testObj, val)
def testObj.m
val
end
testObj
end
t = Test.new
puts t.m
puts inject(t, val).m
答案 0 :(得分:3)
当前的问题是你在第20行打电话
puts inject(t, val).m
即。您将val
作为参数传递给inject
,但您实际上从未定义val
。您需要传递实际值,例如:
puts inject(t, 'Hello, World!').m
首先定义val
:
val = 42
puts inject(t, val).m
但是,如果这样做,您将收到一个新错误:
NameError: undefined local variable or method `val' for #<Test:0x007fa1228439b8>
原因是在Ruby中,只有块可以是闭包。方法不要关闭它们周围的词汇环境。
这意味着:
def inject(testObj, val)
def testObj.m
val
end
testObj
end
你有
val
inject
val
testObj.m
的方法的完全不相关的方法调用
如果您想要访问周围的范围,则需要使用块。值得庆幸的是,有一系列方法可以使用块并定义方法:
def inject(testObj, val)
testObj.define_singleton_method(:m) do
val
end
testObj
end
现在,一切都按预期工作:
puts inject(t, 'Hello, World!').m
# Hello, World!