Ruby обрабатывает ошибки с помощью begin// (эквивалент try/catch/finally в Ruby). Вы исключения и их, а используется для очистки ресурсов. Ruby также позволяет использовать rescue на уровне методов (без явного ) для более чистого кода.
Ruby обрабатывает ошибки с помощью begin// (эквивалент try/catch/finally в Ruby). Вы исключения и их, а используется для очистки ресурсов. Ruby также позволяет использовать rescue на уровне методов (без явного ) для более чистого кода.
rescueensureraiserescueensurebeginbegin
result = risky_operation
rescue ArgumentError => e # rescue a SPECIFIC exception type
puts "Bad argument: #{e.message}"
rescue StandardError => e # broader catch (StandardError, not Exception)
puts "Error: #{e.message}"
retry if attempts < 3 # retry can re-run the begin block
else
puts "succeeded" # runs if NO exception
ensure
cleanup # ALWAYS runs (success or failure)
end
begin/rescue/ensure — это try/catch/finally в Ruby. Ловите специфические типы исключений (rescue ArgumentError), используйте ensure для гарантированной очистки, и else для случая без ошибок. retry может повторить попытку блока.
rescue => e # ✅ bare rescue catches StandardError (the right default)
rescue StandardError # ✅ explicit, same thing
rescue Exception # ❌ AVOID — catches EVERYTHING including system signals
# (Interrupt/Ctrl-C, SystemExit) — can break the program
Важно: простой rescue ловит StandardError (правильное значение по умолчанию для ошибок приложения). Ловля Exception (корня иерархии) ловит всё, включая системные сигналы как Interrupt (Ctrl-C) и SystemExit — которые вы обычно не хотите ловить, так как это может помешать прерыванию программы или её завершению. Это частая ошибка в Ruby.
raise ArgumentError, "Amount must be positive" # raise a built-in
raise "Something failed" # raises RuntimeError
# custom exception class
class InsufficientFundsError < StandardError # inherit from StandardError
def initialize(msg = "Not enough funds")
super
end
end
raise InsufficientFundsError
def process
do_work
rescue => e # rescue WITHOUT begin — applies to the whole method body
handle(e)
ensure
cleanup
end
Правильная обработка исключений необходима для надёжных приложений на Ruby, и понимание подхода Ruby — включая его специфические идиомы и особенности — важно.
Структура begin/rescue/ensure (try/catch/finally в Ruby), ловля конкретных типов исключений, использование ensure для гарантированной очистки и чистый rescue на уровне методов (без явного begin) — это фундаментальные знания, используемые ежедневно.
Особенно важный и специфичный для Ruby пункт — это различие между StandardError и Exception: простой rescue (и правильное значение по умолчанию) ловит StandardError, но ловля Exception (корня иерархии) ловит всё — включая системные сигналы как Interrupt (Ctrl-C) и SystemExit — что вы почти никогда не хотите делать, так как это может помешать прерыванию программы или её завершению, и это частая, вредоносная ошибка.
Понимание того, что вы должны ловить StandardError (не Exception) для ошибок приложения, — это важное знание, специфичное для Ruby, которое предотвращает реальные ошибки.
Знание структуры, пользовательских классов исключений (наследующих от StandardError), retry, идиомы rescue на уровне методов, и особенно различия StandardError-not-Exception важно для написания надёжного, корректного Ruby, который обрабатывает ошибки изящно без нарушения возможности прерывания программы.
Поскольку необработанные ошибки и ошибка Exception-rescuing вызывают реальные проблемы, овладение обработкой исключений в Ruby — её структурой, идиомами и критическим различием между StandardError и Exception — это важное, часто используемое знание для надёжной разработки на Ruby и частая тема интервью.