Могу ли я обнаружить, что метод был переопределен?

Предположим здесь какой-нибудь произвольный код библиотеки, о котором я не знаю:

class Foo
  def hi
  end
end

class Bar < Foo
  def hi
  end
end

И пусть у меня есть код, в котором я передал Bar в качестве параметра.

def check(x)
  do_something_with(x.method(:hi))
end

В приведенном выше примере я могу знать, что x.hi (где x ссылается на экземпляр Bar) отличается от Foo#hi?


Основываясь на ответе Гарета, это то, что у меня есть до сих пор:

def is_overridden?(method)
  name = method.name.to_sym
  return false if !method.owner.superclass.method_defined?(name)
  method.owner != method.owner.superclass.instance_method(name).owner
end

Отвратительный? Великолепная?

Ответ 1

Вы можете сделать это:

if x.method(:hi).owner == Foo

Я далек от того, чтобы быть экспертом по Ruby; Я не удивлюсь, если у кого-то есть лучший способ, чем это.

Ответ 2

Интересный вопрос! Я задавался вопросом о том же вопросе. Вы можете повторно открыть класс Bar и проверить, кто является предками в пути поиска в Bar, которые имеют определенный метод.

class Bar < Foo
  ancestors.each do |ancestor|
    puts ancestor if ancestor.instance_methods.include?(:hi)
  end
end