Menu
Coddy logo textTech

ensure и raise

Часть раздела Логика и управление потоком путешествия по Ruby на Coddy — урок 46 из 56.

Еще два элемента дополняют инструментарий обработки ошибок.

ensure — это блок, который выполняется независимо ни от чего: завершился ли begin нормально, перехватила ли ветка rescue исключение или даже если исключение не было перехвачено. Именно здесь вы размещаете код очистки:

begin
  puts "opening file"
  raise "something broke"
rescue
  puts "caught it"
ensure
  puts "closing file"
end
# открытие файла
# поймано
# закрытие файла

raise — это способ создания собственного исключения. Передайте строку для сообщения или класс вместе с сообщением:

def withdraw(amount)
  raise ArgumentError, "amount must be positive" if amount <= 0
  # ... выполните снятие средств
end

Принято вызывать исключение raise на раннем этапе, в начале метода, чтобы быстро завершить выполнение, если аргументы неверны. Вызывающая сторона может использовать rescue, если у неё есть разумный способ восстановления, или позволить исключению всплыть выше.

challenge icon

Задание

Легко

Определите метод safe_divide(a, b), который:

  • Генерирует исключение ArgumentError с сообщением "b cannot be zero", если b == 0
  • В противном случае возвращает a / b

Затем считайте два целых числа из входных данных. Вызовите safe_divide внутри begin / rescue / ensure:

  • В случае успеха выведите Result: <value>
  • При возникновении ArgumentError выведите Error: <message>
  • В блоке ensure всегда выводите Done.

Для входных данных 10 / 2 вывод будет следующим:

Result: 5
Done.

Для входных данных 10 / 0:

Error: b cannot be zero
Done.

Шпаргалка

ensure выполняется в любом случае (нормальный выход, обработанное или необработанное исключение) — используйте его для очистки ресурсов:

begin
  raise "something broke"
rescue
  puts "caught it"
ensure
  puts "always runs"
end

raise создает исключение. Передайте класс и сообщение, чтобы вызвать исключение определенного типа:

raise ArgumentError, "amount must be positive" if amount <= 0

Соглашение: вызывайте исключение (raise) в начале метода, чтобы быстро завершить работу при некорректных аргументах.

Попробуйте сами

# TODO: определить safe_divide(a, b), вызывает ArgumentError, когда b == 0

a = gets.to_i
b = gets.to_i

# TODO: begin ... вывести Result; rescue ArgumentError => e ... вывести Error; ensure ... вывести Done.
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Логика и управление потоком