Menu
Coddy logo textTech

ensure e raise

Parte da seção Lógica e Fluxo do Journey de Ruby da Coddy — lição 46 de 56.

Mais duas peças completam o kit de ferramentas de tratamento de erros.

ensure é um bloco que executa não importa o que aconteça, seja se o begin terminou normalmente, ou se um ramo rescue capturou uma exceção, ou mesmo se a exceção não foi capturada. É onde você coloca o código de limpeza:

begin
  puts "opening file"
  raise "something broke"
rescue
  puts "caught it"
ensure
  puts "closing file"
end
# abrindo arquivo
# capturado
# fechando arquivo

raise é como você cria sua própria exceção. Passe uma string para a mensagem, ou uma classe mais uma mensagem:

def withdraw(amount)
  raise ArgumentError, "amount must be positive" if amount <= 0
  # ... realize o saque
end

A convenção é usar raise cedo, no topo de um método, para falhar rapidamente quando os argumentos estiverem incorretos. O chamador pode usar rescue se tiver uma recuperação sensata, ou deixar que o erro se propague.

challenge icon

Desafio

Fácil

Defina um método safe_divide(a, b) que:

  • Lança ArgumentError com a mensagem "b cannot be zero" se b == 0
  • Caso contrário, retorna a / b

Em seguida, leia dois inteiros da entrada. Chame safe_divide dentro de begin / rescue / ensure:

  • Em caso de sucesso, imprima Result: <value>
  • Em caso de ArgumentError, imprima Error: <message>
  • No ensure, sempre imprima Done.

Para a entrada 10 / 2, a saída é:

Result: 5
Done.

Para a entrada 10 / 0:

Error: b cannot be zero
Done.

Folha de consulta

ensure executa não importa o que aconteça (saída normal, resgatada ou exceção não capturada) — use-o para limpeza:

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

raise cria uma exceção. Passe uma classe e uma mensagem para lançar um tipo específico:

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

Convenção: use o raise logo no início de um método para falhar rapidamente em caso de argumentos inválidos.

Experimente você mesmo

# TODO: definir safe_divide(a, b), lança ArgumentError quando b == 0

a = gets.to_i
b = gets.to_i

# TODO: begin ... imprimir Result; rescue ArgumentError => e ... imprimir Error; ensure ... imprimir Done.
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Lógica e Fluxo