Rails 3.1: Ruby idiom для предотвращения .each от исключения исключения, если nil?
РЕШЕННО: КАК НЕКОТОРЫЕ КОММЕНТАРИИ УКАЗАНЫ, ПОПУЛЯРНЫЙ ТЕЛЕФОНОВ БЫЛ НИЛЬ, КОГДА ДОЛЖЕН БЫТЬ [].
Есть ли способ использовать .each
, чтобы он не выдавал ошибку, если объект равен нулю или пустой (без добавления дополнительного теста nil/blank?
Кажется, что если я скажу phonelist.each do |phone|
, что если фонетист пуст, то блок не должен выполняться.
Но на мой взгляд (haml) у меня есть - @myvar.phonelist.each do |phone|
, и если фонетист пуст, он выдает NoMethodError.
Я сталкиваюсь с этим много, и всегда обходным путем добавлением явной проверки/ветки для .blank? но кажется, что должен быть более простой способ сказать. Каждый пустые средства ничего не делают.
Ответы
Ответ 1
Вы пытаетесь прибить бандаж по большей проблеме.
Ruby имеет концепцию nil; не может обойти это. Если вы вызываете метод на nil
, вы считаете его действительным, т.е. Ваш дизайн предполагает, что он действителен. Так что на самом деле вопрос: где дыра в вашем дизайне? Почему ваше предположение неверно?
Проблема здесь заключается не в том, что вы не можете вызывать произвольные методы для объекта, который его не поддерживает; проблема в том, что ваши данные считаются действительными, когда, очевидно, это не всегда так.
Но на мой взгляд (haml) у меня есть - @myvar.phonelist.each do | phone | и если фонетист пуст, он выдает NoMethodError.
Нет. Если phonelist
не является объектом, реализующим .each
, он выдает ошибку. Очень разные.
Вы всегда можете инициализировать его пустым массивом, если null, т.е. phonelist ||= []
, но я бы предпочел дизайн, который по возможности обеспечивал бы достоверные данные.
Ответ 2
Вы можете использовать метод try для вызова .each на ноль, чтобы он не выдавал ошибку, если объект равен нулю или пустой.
phonelist = nil
phonelist.try(:each){|i| puts i}
Ответ 3
Просто выполните следующее:
Array(phonelist).each do |phone|
#deal with your phone
end
Array (my_variable) будет гарантировать возврат массива, если my_variable равен нулю.
Он не создает новый массив, если my_variable уже является массивом, поэтому безопасно и легко использовать его везде, где вы хотите!
Ответ 4
Если вы получите phonelist
из хэша (например, проанализированный JSON файл), вы можете использовать fetch
с []
как значение по умолчанию.
phonelist = my_data.fetch('phonelist', [])