Преобразование пустой строки в nil в Ruby
У меня есть строка под названием word
и функция с именем infinitive
такая, что
word.infinitive
будет возвращать другую строку в некоторых случаях и пустую строку в противном случае
Я пытаюсь найти элегантное рубиново однострочное выражение для фрагмента кода ниже
if word.infinitive == ""
return word
else return word.infinitive
Если бы инфинитив вернул нуль вместо "", я мог бы сделать что-то вроде
(word.infinitive or word)
Но так как это не так, я не могу воспользоваться преимуществами короткого замыкания ИЛИ
В идеале я бы хотел, чтобы
1) единственное выражение, которое я могу легко вставлять в другой код
2) функция инфинитива вызывается только один раз
3), чтобы не добавлять какие-либо пользовательские драгоценные камни или плагины в мой код
Ответы
Ответ 1
Если вы не стесняетесь синтаксиса monkeypatching и злоупотребления, это будет работать:
class String
def | x
if empty? then x else self end
end
end
Тогда вы можете сказать word.infinitive | word
, который на самом деле сканирует довольно естественно, если вы спросите меня.
Однако, я думаю, что лучшей идеей было бы изменить метод инфинитива или добавить его версию, которая вернет слово без изменений.
Изменить: Здесь возможно более элегантное решение:
[word.infinitive, word].find {|x| not x.empty?}
Ответ 2
Метод ActiveSupport presence
преобразует пустую строку (или blank?
) в nil
. Он предназначен для вашего конкретного варианта использования:
word.infinitive.presence || word
Обратите внимание, что вы можете легко использовать ActiveSupport вне рельсов:
require 'active_support/core_ext/object/blank'
Ответ 3
Вы можете использовать регулярное выражение, например эта статья предлагает
(word.infinitive[/.+/m] or word) #Fancy way to convert "" to nil
Ответ 4
Соберите правильную вещь - исправьте инфинитив, чтобы он возвращал nils вместо пустых строк или обернул его своим собственным интерфейсом, если вы действительно не можете его трогать.
Ответ 5
Вы можете использовать тернарный оператор (boolean ? true-val : false-val)
с String#empty?
return word.infinitive.empty? ? word : word.infinitive
если вы хотите только один раз вызвать инфинитив:
return (inf = word.infinitive).empty? ? word : inf
Вы также можете рассмотреть возможность добавления в свой код memoization.
Ответ 6
Или вы можете обезвредить новую функцию для String без использования синтаксиса.
class String
def squash
self.empty? ? nil : self
end
end
Теперь вы можете сделать
puts var.squash or "default text"
Я не носитель английского языка, поэтому я не знаю, является ли сквош лучшим словом. Есть ли какое-то слово, которое лучше передало бы идею "превратиться в ноль, только если пусто"?