我知道在Ruby中,我可以使用respond_to?检查一个对象是否有特定的方法。

但是,给定类,我如何检查实例是否有特定的方法?

比如,就像

Foo.new.respond_to?(:bar)

但我觉得肯定有比实例化一个新实例更好的方法。


当前回答

class Foo
 def self.fclass_method
 end
 def finstance_method
 end
end

foo_obj = Foo.new
foo_obj.class.methods(false)
=> [:fclass_method] 

foo_obj.class.instance_methods(false)
=> [:fclass_method] 

希望这对你有所帮助!

其他回答

“给定一个类,看看实例是否有方法(Ruby)”的答案更好。显然Ruby内置了这个功能,但我不知何故忽略了它。不管怎样,我的答案留作参考。

Ruby类响应instance_methods和public_instance_methods方法。在Ruby 1.8中,第一个函数以字符串数组的形式列出所有实例方法名,第二个函数将其限制为公共方法。第二个行为是您最可能想要的,因为respond_to?默认情况下,也将自身限制为公共方法。

Foo.public_instance_methods.include?('bar')

但是在Ruby 1.9中,这些方法返回符号数组。

Foo.public_instance_methods.include?(:bar)

如果您计划经常这样做,您可能希望扩展Module以包含一个快捷方法。(将它分配给Module而不是Class可能看起来很奇怪,但由于instance_methods方法位于模块中,所以最好保持这种模式。)

class Module
  def instance_respond_to?(method_name)
    public_instance_methods.include?(method_name)
  end
end

如果您希望同时支持Ruby 1.8和Ruby 1.9,那么在这里添加搜索字符串和符号的逻辑也很方便。

实际上,这并不适用于对象和类。

这样做:

class TestClass
  def methodName
  end
end

根据给出的答案,这是可行的:

TestClass.method_defined? :methodName # => TRUE

但这并不管用:

t = TestClass.new
t.method_defined? : methodName  # => ERROR!

所以我对类和对象都使用这个:

类:

TestClass.methods.include? 'methodName'  # => TRUE

对象:

t = TestClass.new
t.methods.include? 'methodName'  # => TRUE

而respond_to ?只对公共方法返回true,检查类上的“方法定义”也可能属于私有方法。

在Ruby v2.0+上,可以使用

Foo.private_instance_methods.include?(:bar) || Foo.instance_methods.include?(:bar)

klass.instance_methods。包括:method_name或"method_name",我认为这取决于Ruby版本。

class Foo
 def self.fclass_method
 end
 def finstance_method
 end
end

foo_obj = Foo.new
foo_obj.class.methods(false)
=> [:fclass_method] 

foo_obj.class.instance_methods(false)
=> [:fclass_method] 

希望这对你有所帮助!