Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I detect that a method has been overridden?

Tags:

ruby

Suppose here's some arbitrary library code that I don't know about:

class Foo
  def hi
  end
end

class Bar < Foo
  def hi
  end
end

And suppose I have some code where I'm passed Bar as a parameter.

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

In the above example, can I know that x.hi (where x references an instance of Bar) is different from Foo#hi?


Based on Gareth's answer, this is what I've got so far:

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

Hideous? Gorgeous?

like image 515
Dan Tao Avatar asked Jul 13 '12 00:07

Dan Tao


2 Answers

You could do this:

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

I am far from being a Ruby expert; I will not be surprised if someone has a better way than this.

like image 60
Gareth McCaughan Avatar answered Oct 03 '22 23:10

Gareth McCaughan


Interesting question! I wondered about the same question. You can reopen Bar class and check who are the ancestors in the lookup path of Bar that have the method defined.

class Bar < Foo
  ancestors.each do |ancestor|
    puts ancestor if ancestor.instance_methods.include?(:hi)
  end
end
like image 35
Wei Avatar answered Oct 04 '22 00:10

Wei