检查是否在类上定义了方法

如何检查方法是否直接在某个类上定义,而不是通过inheritance或包含/扩展? 我想要’foo’之类的东西? 在下面的:

class A def a; end end module B def b; end end class C  false C.foo?(:b) #=> false C.foo?(:c) #=> true 

用这个:

 C.instance_methods(false).include?(:a) C.instance_methods(false).include?(:b) C.instance_methods(false).include?(:c) 

方法instance_methods返回此类的实例将具有的方法Array。 将false作为第一个参数传递仅返回此类的方法,而不返回超类的方法。

因此, C.instance_methods(false)返回C定义的方法列表。

然后你只需要检查该方法是否在返回的数组中(这是include?调用的内容)。

查看文档

对于对象,您可以使用Object.respond_to? 。

如果obj响应给定方法,则返回true。

对于类,请查看Module.instance_methods

返回一个数组,其中包含接收器中公共和受保护实例方法的名称。

不完全是问题的答案,但是如果你正在阅读这个问题,你可能会对此感兴趣,它使用.instance_methods(false)

 class Object # This is more or less how Ruby does method lookup internally def who_responds_to?(method, klass_ancestors = nil) if klass_ancestors.nil? return who_responds_to?(method, self.class.ancestors) end if klass_ancestors.empty? return nil end if klass_ancestors[0].instance_methods(false).include?(method) return klass_ancestors[0] end klass_ancestors.shift who_responds_to?(method, klass_ancestors) end end 

例如

 class Person end module Drummer def drum end end module Snowboarder def jump end end module Engineer def code end end class Bob < Person include Drummer include Snowboarder include Engineer def name end end puts "who responds to name" puts bob.who_responds_to?(:name) puts "\n" puts "who responds to code" puts bob.who_responds_to?(:code) puts "\n" puts "who responds to jump" puts bob.who_responds_to?(:jump) puts "\n" puts "who responds to drum" puts bob.who_responds_to?(:drum) puts "\n" puts "who responds to dance" puts bob.who_responds_to?(:dance) 

产量

 who responds to name Bob who responds to code Engineer who responds to jump Snowboarder who responds to drum Drummer who responds to dance [this line intentionally blank because return value is nil]