Во время работы программы мы можем столкнуться с различными ошибками, о которых нас любезно оповещает Ruby. Удобно, когда тебе не нужно включать дебаг, а досаточно просто внимательно прочитать ошибку и ее исправить.
Отлов ошибок
Но одно дело натыкаться на эти ошибки во время разработки, а другое дело, когда эти ошбки видит наш конечный пользователь. Для того, чтобы нам защититься от неожиданного поведения программы существует понятие отлов ошибок. В Ruby для этого мы можем воспользоваться конструкцией begin ... end.
user_input =gets.chomp.to_iputs10% user_input
простейшая программа, которая получает пользовательский ввод и делит 10 на полученное число. Но вот не задача, пользователь вводит 0, а как мы знаем, делить на 0 нельзя. В итоге получим ошибку ZeroDivisionError. Давайте исправим ситуацию:
user_input =gets.chomp.to_i# все что находится между begin и rescue будет проверяться на ошибки# если ошибка срабатывает, то начинает работать логика между rescue и end beginputs10% user_input# после rescue мы указываем ошибку, которую мытаемся отловить# err - объект класса ошибки которую отлавливаемrescueZeroDivisionError=> error# Важно в случае ошибок не просто обработать и дать корректный ответ# но и не потерять информацию об ошибке, например написать ее в консольp errorputs0# количество отлавлиемых ошибок может быть сколько угодно# Если ошибка не является объектом класса первой отлавливаемой ошибки, значит проверяется следующий rescue тд.rescueArgumentError=> errorputs"Ошибка: Некорректный формат введенных данных. #{error.inspect}"end# если мы отловили ошибку, то после кода внутри rescue программа начем работать дальшеputs"finish"
В целом begin ... rescue ... end по своему виду очень похож на if ... elsif ... else ... end, только в одном случае мы проверяем условия, а в другом тип ошибки.
Создание собственных
Как Ruby выкидывает нам свою ошибку, так и мы можем выкидывать свои собственные ошибки.
Для начала создадим класс ошибки и унаследуем его от StandardError:
classMyError<StandardErrordefinitialize(message)# любая ошибка имеет внутри себя сообщение об ошибке, которое в случае чего показывается в консоли# например ZeroDivisionError имеет текст "divided by 0"super(message)endend
Теперь нам нужно выбросить эту самую ошибку
defexample(arg)if arg >10# выброс ошибки отличается от создание объекта# нсачала пишем raise, потом класс ошибки, потом текст, который будет передан в метод initializeraiseMyError,"helpful description for error"elseputs"It is argument - #{arg}"endendbegin# Сначала в консоль распечатается 'It is argument - 1' example(1)# Здесь уже сработает наша ошибка example(20)# Отловили нашу ошибкуrescueMyError=> error# Теперь в консоль напечаталось 'It is MyError - helpful description for error'puts"It is MyError - #{error.message}"end