2010-04-02 63 views
15

response_to可能并不那么明显?以红宝石工作。 考虑以下因素:respond_to?和受保护的方法


class A 

    def public_method 
    end 

    protected 
    def protected_method 
    end 

    private 
    def private_method 
    end 

end 

obj = A.new 
obj.respond_to?(:public_method) 
# true - that's pretty obvious 
obj.respond_to?(:private_method) 
# false - as expected 
obj.respond_to?(:protected_method) 
# true - WTF? 

所以,如果 'OBJ' 响应protected_method我们应该期待

obj.protected_method 

没有引发异常,不是吗?

...但它明显提高

调用respond_to的文档点?与第二个参数设置为true检查私有方法以及

obj.respond_to?(:private_method, true) 
# true 

而这更为合理

所以,问题是如何检查对象只响应公众的方法? 有没有比这更好的解决方案?

obj.methods.include?(:public_method) 
# true 
obj.methods.include?(:protected_method) 
# false 

回答

8

它正在辩论是否应该respond_to?寻求保护的方法或没有(检查this issue

马茨曾表示,它可能会在Ruby中2.0改变。

注意一些类可能使用#method_missing和专业#respond_to?(通过或更好指定在Ruby #respond_to_missing? 1.9.2+),在这种情况下,您obj.methods.include?将不可靠。

+0

我很难理解翻译日语,但无论如何,很高兴知道红宝石核心考虑这个问题。至少有一个可以使用obj.class.public_method_defined?(:protected_method),它的工作方式与预期的一样,但不会处理单例方法,所以我认为这是一种解决方法,而不是真正的解决方案 – mlomnicki 2010-04-03 01:24:13

+0

回答更新信息 – 2011-11-24 21:55:10

11

documentation:如果obj响应给定的方法

返回true。私人和 保护的方法都包含在仅当可选 第二个参数的计算结果为真

当问题被写入搜索(红宝石1.8.7):

返回true如果obj回应给定的方法。只有当可选的第二个参数的计算结果为true时,私有方法才会包含在搜索中。

+1

问题是从2010 。然后在Ruby 1.8.7中,文档声明:“如果obj响应给定的方法,则返回true”。只有当可选的第二个参数的计算结果为true时,私有方法才会包含在搜索中。 – steenslag 2014-06-25 15:48:36

+1

仍然是一个有价值的答案。当从Ruby'1.8.7'升级到Ruby' 2.1.1'时,我发现了这个奇怪的bug。 – 2014-08-12 23:41:39

+0

现在它在[ruby-doc.org](http://ruby-doc.org/core-2.2.1/Object.html#method-i-respond_to-3F)上。 – 2015-03-25 12:41:47