Сделайте что-нибудь, если значение присутствует

Я часто нахожу, что пишу 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 или хотя активна поддержка?

Я открыл запрос на перенос для этой функции.

3 ответа

Вы можете использовать комбинацию presence и try:

Если try вызывается без аргументов, он возвращает получателю данный блок, если он не равен nil:

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


Вы можете попробовать

do_thing(object.attribute) if object.attribute

Это нормально, если атрибут не является логическим. В этом случае он не будет вызывать, если значение false.

Если ваш атрибут может быть ложным, используйте .nil?.

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


Несмотря на отсутствие такой функциональности из коробки, можно сделать:

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

С другой стороны, Rails предоставляет так много monkeypatches, что можно было бы добавить один в этот цирк:

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

licensed under cc by-sa 3.0 with attribution.