Answers:
我不知道为什么每个人都建议您使用该工具instance_methods
以及include?
何时进行method_defined?
该工作。
class Test
def hello; end
end
Test.method_defined? :hello #=> true
注意
如果您是从另一种面向对象语言来的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类型的字符串)。
String.instance_methods(false).include? :freeze
,但是false参数可以准确说明freeze
方法是否在String类中定义。在这种情况下,它将返回false,因为freeze
方法是由String从Kernel模块继承的,但String.method_defined? :freeze
始终将返回true,这对于实现此目的无济于事。
method_defined?
必须在类(例如Array
)上使用,但是您尝试在实例(例如[]
)上使用它
您可以使用method_defined?
以下方法:
String.method_defined? :upcase # => true
比instance_methods.include?
其他所有人似乎都建议的要容易,便携和高效。
请记住,您将不会知道类是否通过某些方式动态响应某些调用method_missing
,例如通过重新定义respond_to?
,或者从Ruby 1.9.2开始通过定义respond_to_missing?
。
instance.class.method_defined? :upcase
实际上,这不适用于对象和类。
这样做:
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_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,那将是添加逻辑以同时搜索字符串和符号的便捷位置。
method_defined?
更好:)
尝试 Foo.instance_methods.include? :bar
我认为method_defined?
Rails 出了点问题。它可能不一致或类似,所以如果您使用Rails,最好使用中的attribute_method?(attribute)
。
“ 测试的method_defined?上的ActiveRecord类而不是以前的一个实例工作 ”是一个关于不一致的问题。
如果要检查对象是否可以响应一系列方法,则可以执行以下操作:
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。
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 2.5.3的案例中,以下句子非常有效:
value = "hello world"
value.methods.include? :upcase
它将返回布尔值true或false。