monkeypatching问题

时间:2012-07-23 16:26:25

标签: ruby monkeypatching

我正在使用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

1 个答案:

答案 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!