猴子修补:define_method优先于bind吗?

wil*_*484 4 ruby

在下面的代码片段中,我Foo#bar用一个define_method块来修补补丁.初始化一个新实例后Foo,我通过bind调用父类bar方法覆盖它,但是当我调用该方法时,调用该块定义的define_method块.为什么bind调用不会改变方法的行为?

class OriginalFoo
  def bar
    puts 'in OriginalFoo!'
  end
end

class Foo < OriginalFoo
  def bar
    puts 'in Foo'
  end
end

class Foo < OriginalFoo
  old_bar = instance_method(:bar)
  define_method(:bar) do
    puts 'in define_method block'
    old_bar.bind(self).call
  end
end

foo_instance = Foo.new # => #<Foo:0x00007fe3ff037038>
OriginalFoo.instance_method(:bar).bind(foo_instance) # => #<Method: OriginalFoo#bar>
foo_instance.bar
# >> in define_method block
# >> in Foo
Run Code Online (Sandbox Code Playgroud)

mu *_*ort 7

你误解了它是如何UnboundMethod#bind运作的.你打电话Module#instance_method来得到一个UnboundMethod(即没有a的方法self):

OriginalFoo.instance_method(:bar)
# #<UnboundMethod: ... >
Run Code Online (Sandbox Code Playgroud)

然后你调用UnboundMethod#bind附加一个self方法,返回一个Method实例:

m = OriginalFoo.instance_method(:bar).bind(foo_instance)
# => #<Method: ...>
Run Code Online (Sandbox Code Playgroud)

但这不会改变方法foo_instance,它所做的一切就是让self你说的foo_instance时间(或者如果)m.call:um.bind(obj)不做任何事情obj,它只是给你um一个Methodobj它的东西self.