给定一个类,看看实例是否有方法(Ruby)

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

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

即类似的东西

 Foo.new.respond_to?(:bar) 

但是我觉得要比实例化一个新实例更好。

我不知道为什么每个人都build议你应该使用instance_methodsinclude? 何时method_defined? 做这个工作。

 class Test def hello; end end Test.method_defined? :hello #=> true 

你可以使用method_defined? 如下:

 String.method_defined? :upcase # => true 

instance_methods.include?更容易,便携和高效instance_methods.include? 其他人似乎都在暗示。

请记住,您将不知道某个类是否通过method_missingdynamic响应某些调用,例如通过重新定义respond_to? 或者从Ruby 1.9.2开始,通过定义respond_to_missing?

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

这样做:

 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 

“ 给定一个类,看实例是否有方法(Ruby) ”的答案比较好。 Ruby显然有这个内置的,我不知何故错过了它。 无论如何,我的答案留给参考。

Ruby类对方法instance_methodspublic_instance_methods作出响应。 在Ruby 1.8中,第一个列出了string数组中的所有实例方法名,第二个将其限制为公共方法。 第二个行为是你最想要的,因为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,那么添加逻辑来searchstring和符号也是一个很方便的地方。

不知道这是否是最好的方法,但你可以一直这样做:

 Foo.instance_methods.include? 'bar' 

如果你正在检查一个对象是否可以响应一系列的方法,你可以这样做:

 methods = [:valid?, :chase, :test] def has_methods?(something, methods) methods & something.methods == methods end 

methods & something.methods将在它们的公共/匹配元素上连接这两个数组。 something.methods包括所有你正在检查的方法,它将等于方法。 例如:

 [1,2] & [1,2,3,4,5] ==> [1,2] 

所以

 [1,2] & [1,2,3,4,5] == [1,2] ==> true 

在这种情况下,你会想要使用符号,因为当你调用.methods时,它将返回一个符号数组,如果你使用["my", "methods"] ,它会返回false。

试试Foo.instance_methods.include? :bar Foo.instance_methods.include? :bar

我认为method_defined? 在Rails中。 这可能是不一致的,所以如果你使用Rails,最好使用attribute_method?(attribute)

“ 在实例化之前,对ActiveRecord类的method_defined进行testing是不可行的 ”,这是一个关于不一致性的问题。

klass.instance_methods.include :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] 

希望这可以帮助你!

Interesting Posts