Ответ 1
В Ruby 2.3.0 добавлен безопасный навигационный оператор (&.
), который проверяет нуль перед вызовом метода.
s&.strip
Он вернет nil
, если s
равен nil
, а не поднимает NoMethodError
.
У меня есть строка в Ruby, на которой я вызываю метод strip для удаления начального и конечного пробелов. например.
s = "12345 "
s.strip
Однако, если строка пуста, я получаю следующую ошибку.
NoMethodError: undefined метод `strip 'для nil: NilClass
Я использую Ruby 1.9, так что самый простой способ проверить, равно ли значение nil перед вызовом метода strip?
Update:
Я попробовал это на элементе в массиве, но получил ту же проблему:
data[2][1][6].nil? ? data[2][1][6] : data[2][1][6].split(":")[1].strip
В Ruby 2.3.0 добавлен безопасный навигационный оператор (&.
), который проверяет нуль перед вызовом метода.
s&.strip
Он вернет nil
, если s
равен nil
, а не поднимает NoMethodError
.
Вы можете использовать метод try
из ActiveSupport (библиотека Rails)
gem install activesupport
require 'active_support/core_ext/object/try'
s.try(:strip)
или вы можете использовать мой драгоценный камень tryit, который дает дополнительные возможности:
gem install tryit
s.try { strip }
Если вы не возражаете против создания дополнительного объекта, любая из этих работ:
"#{s}".strip
s.to_s.strip
Без дополнительного объекта:
s && s.strip
s.strip if s
Я думаю, самый простой способ:
s.strip if s
ActiveSupport
поставляется с методом для этого: try
. Например, an_object.try :strip
вернет nil
, если an_object
равен нулю, но будет действовать иначе. Синтаксис такой же, как send
. Cf active_support_core_extensions.html#try.
Метод, который работает для меня (я знаю, я никогда не должен загрязнять нетронутое пространство Object
, но это так удобно, что я буду рисковать):
class Object
def unless_nil(default = nil, &block)
nil? ? default : block[self]
end
end
p "123".unless_nil(&:length) #=> 3
p nil.unless_nil("-", &:length) #=> "-"
В вашем конкретном случае это может быть:
data[2][1][6].unless_nil { |x| x.split(":")[1].unless_nil(&:strip) }
Если вы хотите избежать ошибки, возникающей в вопросе:
s.to_s.strip
Проще говоря:
s = s.nil? ? s : s.strip
Tl; dr Проверьте, если s равно nil, затем верните s, иначе разделите его.
Вы можете просто сделать это
s.try(:strip)
Я бы выбрал решение, в котором s
никогда не может быть nil
для начала.
Вы можете использовать оператор ||
для передачи значения по умолчанию, если some_method
возвращает ложное значение:
s = some_method || '' # default to an empty string on falsy return value
s.strip
Или, если s
уже назначен, вы можете использовать ||=
, который делает то же самое:
s ||= '' # set s to an empty string if s is falsy
s.strip
Предоставление сценария по умолчанию для отсутствия параметров или переменных является хорошим способом поддержания чистоты кода, поскольку вам не нужно смешивать логику с проверкой переменных.