Сокращение Ruby для "используйте это, если оно не пустое, иначе используйте это"
У меня есть следующий код:
url = file.s3_url.blank? ? file.url : file.s3_url
Есть ли более короткий способ написать это?
Спасибо!
Ответы
Ответ 1
Ну, вы можете написать метод на любом file
экземпляре (скажем S3File
):
class S3File
def real_url
self.s3_url.blank? ? self.url : self.s3_url
end
#...
end
Тогда он становится реальным простым:
url = file.real_url
Как сказал @tokland, вы можете использовать патч Object
для использования метода or_if
, который будет реализован следующим образом:
class Object
def or_if(method, val = nil)
self.send(method) ? (block_given? ? yield : val) : self
end
end
Таким образом, вы сможете сделать это:
url = file.s3_url.or_if(:blank?) { file.url }
Или это:
url = file.s3_url.or_if(:blank?, file.url)
Ответ 2
В ActiveSupport есть абстракция, Наличие объекта #:
url = file.s3_url.presence || file.url
Ответ 3
Возможно, вы можете сделать следующее:
url = file.s3_url || file.url
Этот код будет использовать file.url, только если file.s3_url равен нулю. Это означает, что пустая строка не будет работать. Если вы хотите убедиться, что пустая строка не используется, как и в вашем примере, тогда нет более короткого способа сделать это.
Ответ 4
Я использую утилитный метод.
def until_not_blank(*args)
args.find {|a| !a.blank? }
end
url = until_not_blank(file.s3_url, file.url)
Обычно я просто добавляю это в свой ApplicationController и делаю его помощником. Если вы хотите, чтобы он был доступен по всему миру, вы могли бы поместить его в ядро, или вы могли бы патч-арки
class Array
def first_not_blank
find {|a| !a.blank?}
end
end
url = [file.s3_url, file.url].first_not_blank
Ответ 5
url = (file.s3_url.blank? && file.s3_url) || file.url
Выглядит круто, но на самом деле я нахожу это запутанным и предпочитаю старый добрый троичный, если.