Подтвердить что ты не робот

Рубин Oneline Rescue

Недавно я узнал, что вы можете использовать rescue в строке кода, если что-то пойдет не так в этой строке (см. http://www.rubyinside.com/21-ruby-tricks-902.html Совет № 21). У меня есть код, который выглядел так:

if obj['key'] && obj['key']['key2'] && obj['key']['key2']['name']
  name = obj['key']['key2']['name']
else
  name = ''
end

С помощью метода rescue, я считаю, что могу изменить этот код на что-то вроде этого:

name = obj['key']['key2']['name'] rescue ''

Если исключение nil выбрано на любом уровне доступа к хешу, оно должно быть пойманным спасением и дать мне '', что я и хочу. Я также мог бы выбрать имя nil, если это было желаемое поведение.

Есть ли какая-то известная опасность в этом? Я спрашиваю, потому что это кажется слишком хорошим, чтобы быть правдой. У меня есть очень уродливый код, который я бы хотел избавиться от этого, похоже на первый пример кода.

4b9b3361

Ответ 1

Читает хорошо! Но это поразит вашу работу. По моему опыту rescue намного медленнее, когда он срабатывает и немного медленнее, когда нет. Во всех случаях if работает быстрее. Другая вещь, которую следует учитывать, заключается в том, что исключений не следует ожидать, и вы относитесь к этому коду. Наличие хэша, столь глубоко вложенного, может быть хорошим запахом, что рефакторинг является nede

Ответ 2

Этот конкретный пример теперь можно достичь с помощью Ruby 2.3 метод генерации.

name = obj.dig 'key', 'key2', 'name'

Это обеспечит безопасный доступ к obj['key']['key2']['name'], возвращая нуль, если какой-либо шаг завершится неудачно.

(В общем, обычно рекомендуется использовать исключения только для реальных непредвиденных ошибок, хотя это понятно в примере, подобном этому, если синтаксис делает его громоздким.)

Ответ 3

Ядро:: рейз может оказаться полезным и посмотреть

if obj['key']['key2']['name']
  name = obj['key']['key2']['name']
else
  raise ''
end