mxgrn
mxgrn

Reputation: 1778

Detecting that a method was not overridden

Say, I have the following 2 classes:

class A
  def a_method
  end
end

class B < A
end

Is it possible to detect from within (an instance of) class B that method a_method is only defined in the superclass, thus not being overridden in B?

Update: the solution

While I have marked the answer of Chuck as "accepted", later Paolo Perrota made me realize that the solution can apparently be simpler, and it will probably work with earlier versions of Ruby, too.

Detecting if "a_method" is overridden in B:

B.instance_methods(false).include?("a_method")

And for class methods we use singleton_methods similarly:

B.singleton_methods(false).include?("a_class_method")

Upvotes: 6

Views: 633

Answers (4)

Paolo Perrotta
Paolo Perrotta

Reputation: 623

class A
  def m1; end
  def m2; end
end

class B < A
  def m1; end
  def m3; end
end

obj = B.new
methods_in_class = obj.class.instance_methods(false)  # => ["m1", "m3"]
methods_in_superclass = obj.class.superclass.instance_methods(false)  # => ["m2", "m1"]
methods_in_superclass - methods_in_class  # => ["m2"]

Upvotes: 2

Chuck
Chuck

Reputation: 237110

If you're using Ruby 1.8.7 or above, it's easy with Method#owner/UnboundMethod#owner.

class Module
  def implements_instance_method(method_name)
    instance_method(method_name).owner == self
    rescue NameError
    false
  end
end

Upvotes: 7

Dafydd Rees
Dafydd Rees

Reputation: 6983

Given an object b which is an instance of B, you can test to see whether b's immediate superclass has a_method:

b.class.superclass.instance_methods.include? 'a_method'

Notice that the test is against the method name, not a symbol or a method object.

"thus not being overridden in B" - Just knowing that the method is only defined in A is difficult because you can define the method on an individual instances of A and B... so I think it's going to be difficult to test that a_method is only defined on A, because you'd have to round up all the subclasses and subinstances in the system and test them...

Upvotes: 0

ennuikiller
ennuikiller

Reputation: 46985

you can always to the following and see if its defined there:

a = A.new

a.methods.include?(:method)

Upvotes: 0

Related Questions