Исправление обезьяны: имеет ли define_method приоритет над привязкой? - PullRequest
0 голосов
/ 31 августа 2018

В приведенном ниже фрагменте кода я использую патч 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

1 Ответ

0 голосов
/ 31 августа 2018

Вы не понимаете, как работает UnboundMethod#bind. Вы вызываете Module#instance_method, чтобы получить UnboundMethod (то есть метод без self):

OriginalFoo.instance_method(:bar)
# #<UnboundMethod: ... >

Затем вы вызываете UnboundMethod#bind, чтобы присоединить self к этому методу, который возвращает a Method экземпляр:

m = OriginalFoo.instance_method(:bar).bind(foo_instance)
# => #<Method: ...>

Но это не изменит метод в foo_instance, все, что он делает, это делает self вашим foo_instance, когда (или если) вы сказали m.call: um.bind(obj) ничего не делает для obj, это просто дает вам um как Method, который имеет obj в качестве self.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...