避免重复的response_to?调用

时间:2012-11-30 22:55:51

标签: ruby dry

我需要检查对象是否响应任意数量的方法。

我厌倦了这样做:

if a.respond_to?(:foo) && a.respond_to?(:bar) && a.respond_to?(:blah)

什么是更“正确”的DRY方式呢?

4 个答案:

答案 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是什么类型,这可能是一个有趣的案例。发布更多代码!