我知道在Ruby中,我可以使用respond_to?检查一个对象是否有特定的方法。
但是,给定类,我如何检查实例是否有特定的方法?
比如,就像
Foo.new.respond_to?(:bar)
但我觉得肯定有比实例化一个新实例更好的方法。
我知道在Ruby中,我可以使用respond_to?检查一个对象是否有特定的方法。
但是,给定类,我如何检查实例是否有特定的方法?
比如,就像
Foo.new.respond_to?(:bar)
但我觉得肯定有比实例化一个新实例更好的方法。
当前回答
klass.instance_methods。包括:method_name或"method_name",我认为这取决于Ruby版本。
其他回答
你可以使用method_defined?如下:
String.method_defined? :upcase # => true
比instance_methods.include?其他人似乎都在建议。
请记住,你不会知道一个类是否动态响应一些调用method_missing,例如通过重新定义respond_to?,或者从Ruby 1.9.2开始定义respond_to_missing?。
我不知道为什么每个人都建议你应该使用instance_methods和include?当method_defined ?完成任务。
class Test
def hello; end
end
Test.method_defined? :hello #=> true
NOTE
如果你是从其他OO语言来的Ruby,或者你认为method_defined的意思是你显式定义的方法:
def my_method
end
然后读这个:
在Ruby中,模型上的属性基本上也是一个方法。所以method_defined ?对于属性也将返回true,而不仅仅是方法。
例如:
给定一个具有String属性first_name的类实例:
<instance>.first_name.class #=> String
<instance>.class.method_defined?(:first_name) #=> true
因为first_name既是一个属性也是一个方法(也是一个string类型的字符串)。
而respond_to ?只对公共方法返回true,检查类上的“方法定义”也可能属于私有方法。
在Ruby v2.0+上,可以使用
Foo.private_instance_methods.include?(:bar) || Foo.instance_methods.include?(:bar)
实际上,这并不适用于对象和类。
这样做:
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
不确定这是否是最好的方法,但你总是可以这样做:
Foo.instance_methods.include? 'bar'