Menu
Coddy logo textTech

ensure y raise

Parte de la sección Lógica y flujo del Journey de Ruby de Coddy — lección 46 de 56.

Dos piezas más completan el kit de herramientas para el manejo de errores.

ensure es un bloque que se ejecuta pase lo que pase, ya sea que begin haya terminado normalmente, o que una rama rescue haya capturado una excepción, o incluso si la excepción no fue capturada. Es donde se coloca el código de limpieza:

begin
  puts "opening file"
  raise "something broke"
rescue
  puts "caught it"
ensure
  puts "closing file"
end
# abriendo archivo
# capturado
# cerrando archivo

raise es como creas tu propia excepción. Pasa una cadena para el mensaje, o una clase más un mensaje:

def withdraw(amount)
  raise ArgumentError, "amount must be positive" if amount <= 0
  # ... realizar el retiro
end

La convención es usar raise temprano, al principio de un método, para fallar rápido cuando los argumentos son incorrectos. El llamador puede usar rescue si tiene una recuperación sensata, o dejar que se propague.

challenge icon

Desafío

Fácil

Define un método safe_divide(a, b) que:

  • Lanza ArgumentError con el mensaje "b cannot be zero" si b == 0
  • De lo contrario, devuelve a / b

Luego lee dos enteros de la entrada. Llama a safe_divide dentro de begin / rescue / ensure:

  • En caso de éxito, imprime Result: <value>
  • En caso de ArgumentError, imprime Error: <message>
  • En ensure, siempre imprime Done.

Para la entrada 10 / 2, la salida es:

Result: 5
Done.

Para la entrada 10 / 0:

Error: b cannot be zero
Done.

Hoja de referencia

ensure se ejecuta pase lo que pase (salida normal, rescatada o excepción no capturada); úsalo para la limpieza:

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

raise crea una excepción. Pasa una clase y un mensaje para lanzar un tipo específico:

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

Convención: usa raise temprano al principio de un método para fallar rápido ante argumentos incorrectos.

Pruébalo tú mismo

# TODO: definir safe_divide(a, b), lanza ArgumentError cuando b == 0

a = gets.to_i
b = gets.to_i

# TODO: begin ... imprimir Result; rescue ArgumentError => e ... imprimir Error; ensure ... imprimir Done.
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Lógica y flujo