仅在存在时调用方法

时间:2013-04-03 12:39:33

标签: ruby-on-rails ruby

是否存在一些隐藏的Ruby / Rails-magic,只有在存在时才调用方法?

让我说我想打电话

resource.phone_number

但我事先并不知道资源是否响应phone_number。一种方法是

resource.phone_number if resource.respond_to? :phone_number

如果在错误的地方使用,那就不是那么好了。我很好奇是否存在更符合try使用方式的内容(resource.try(:phone_number))。

6 个答案:

答案 0 :(得分:34)

如果您对标准ruby语法不满意,可以自由选择:

class Object
  def try_outside_rails(meth, *args, &cb)
    self.send(meth.to_sym, *args, &cb) if self.respond_to?(meth.to_sym)
  end
end

现在:

resource.try_outside_rails(:phone_number)

会按照您的意愿行事。

答案 1 :(得分:15)

我会尝试defined?http://ruby-doc.org/docs/keywords/1.9/Object.html#defined-3F-method)。它似乎完全符合你的要求:

resource.phone_number if defined? resource.phone_number

答案 2 :(得分:12)

我知道这是很老的帖子。但只是想知道这是否是一个可能的答案以及影响是否相同。

resource.try(:phone_number) rescue nil

由于

答案 3 :(得分:1)

从Ruby 2.3.0开始(现在仍处于预览阶段),您可以使用新的safe navigation operator

resource&.phone_number

如果有人对所选语法感兴趣,我建议您查看Ruby问题跟踪系统中的feature request讨论。我也在答案here中解释了推理。

答案 4 :(得分:1)

我不能代表效率,但是类似...

Klass.methods.include?(:method_name) 

在Rails 4中为我工作

答案 5 :(得分:-1)

如果A.c已定义且A.aA.b未定义,则可以执行A.a rescue A.b rescue A.c,它将像魅力一样工作。不过,你会打破一些愚蠢的规则。