我需要检查对象是否响应任意数量的方法。
我厌倦了这样做:
if a.respond_to?(:foo) && a.respond_to?(:bar) && a.respond_to?(:blah)
什么是更“正确”的DRY方式呢?
答案 0 :(得分:3)
您始终可以将其包装在辅助方法中:
def has_methods?(obj, *methods)
methods.all?{|method| obj.respond_to? method}
end
答案 1 :(得分:2)
如果你没有反对monkeypatching的话,试试这个:
class Object
def respond_to_all? *meths
meths.all? { |m| self.respond_to?(m) }
end
def respond_to_any? *meths
meths.any? { |m| self.respond_to?(m) }
end
end
p 'a'.respond_to_all? :upcase, :downcase, :capitalize
#=> true
p 'a'.respond_to_all? :upcase, :downcase, :blah
#=> false
p 'a'.respond_to_any? :upcase, :downcase, :blah
#=> true
p 'a'.respond_to_any? :upcaze, :downcaze, :blah
#=> false
更新:使用meths.all?
和meths.any?
。 @MarkThomas,谢谢你让我神清气爽。
更新:修复responsd
错字。
答案 2 :(得分:0)
检查Active Support
的{{1}}扩展名。
它有方法try。由于缺乏上下文,很难说你如何使用这种方法,可能是这样的:
Rails
为了使用这种方法你应该
if a.try(:foo) && a.try(:bar) && a.try(:blah)
另请检查此方法的版本tryit:
答案 3 :(得分:0)
“正确”的方式(或许多方面之一)是Tell Do Not Ask,这意味着如果您向对象发送消息,您希望它在没有抱怨的情况下做出响应。这也被称为鸭子打字(如果它可以嘎嘎叫,它是鸭子)。
我不能给你任何具体的建议,因为你没有问过具体的问题。如果您正在测试三种不同的方法,您似乎不知道对象a
是什么类型,这可能是一个有趣的案例。发布更多代码!