如果存在价值就做某事

Do something if value is present

我经常发现自己在编写 Ruby 代码时检查是否存在某个值,如果存在则随后对该值执行某些操作。例如

if some_object.some_attribute.present?
  call_something(some_object.some_attribute)
end

如果能写成这样就好了

some_object.some_attribute.presence { |val| call_something(val) }
=> the return value of call_something

有人知道 Ruby 或 activesupport 中是否有这样的功能吗?

我为此功能打开了 pull request

你可以试试

do_thing(object.attribute) if object.attribute

这通常没问题,除非属性是布尔值。在这种情况下,如果值为 false,它将不会调用。

如果您的属性可以为假,请改用 .nil?

do_thing(object.attribute) unless object.attribute.nil?

您可以使用 presence and try:

的组合

If try is called without arguments it yields the receiver to a given block unless it is nil:

'foo'.presence.try(&:upcase)
#=> "FOO"

' '.presence.try(&:upcase)
#=> nil

nil.presence.try(&:upcase)
#=> nil

虽然没有开箱即用的功能,但可以这样做:

some_object.some_attribute.tap do |attr|
  attr.present? && call_smth(attr) 
end

另一方面,Rails 提供了如此多的猴子补丁,可以将一个添加到这个马戏团:

class Object
  def presense_with_rails
    raise 'Block required' unless block_given?
    yield self if self.present? # requires rails
  end
  def presense_without_rails
    raise 'Block required' unless block_given?
    skip = case self
           when NilClass, FalseClass then true
           when String, Array then empty?
           else false
           end
    yield self unless skip
  end
end