ensure and raise
Part of the Logic & Flow section of Coddy's Ruby journey — lesson 46 of 56.
Two more pieces complete the error-handling toolkit.
ensure is a block that runs no matter what, whether begin finished normally, or a rescue branch caught an exception, or even if the exception was uncaught. It's where you put cleanup code:
begin
puts "opening file"
raise "something broke"
rescue
puts "caught it"
ensure
puts "closing file"
end
# opening file
# caught it
# closing fileraise is how you create your own exception. Pass a string for the message, or a class plus a message:
def withdraw(amount)
raise ArgumentError, "amount must be positive" if amount <= 0
# ... do the withdrawal
endThe convention is to raise early, at the top of a method, to fail fast when arguments are wrong. The caller can rescue if they have a sensible recovery, or let it bubble up.
Challenge
EasyDefine a method safe_divide(a, b) that:
- Raises
ArgumentErrorwith the message"b cannot be zero"ifb == 0 - Otherwise returns
a / b
Then read two integers from input. Call safe_divide inside begin / rescue / ensure:
- On success, print
Result: <value> - On
ArgumentError, printError: <message> - In
ensure, always printDone.
For input 10 / 2, the output is:
Result: 5
Done.For input 10 / 0:
Error: b cannot be zero
Done.Cheat sheet
ensure runs no matter what (normal exit, rescued, or uncaught exception) — use it for cleanup:
begin
raise "something broke"
rescue
puts "caught it"
ensure
puts "always runs"
endraise creates an exception. Pass a class and message to raise a specific type:
raise ArgumentError, "amount must be positive" if amount <= 0Convention: raise early at the top of a method to fail fast on bad arguments.
Try it yourself
# TODO: define safe_divide(a, b), raises ArgumentError when b == 0
a = gets.to_i
b = gets.to_i
# TODO: begin ... print Result; rescue ArgumentError => e ... print Error; ensure ... print Done.
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Logic & Flow
1Strings In Depth
String Methods OverviewString InterpolationIterating Over StringsSplit and JoinRecap - String Weaver4Blocks, Procs & Lambdas
What is a Block?do..end vs BracesThe yield KeywordBlock ParametersProcs and LambdasRecap - Custom Iterator7Hashes Part 2
Hash.new with DefaultsIterating HashesNested HashesMerging and TransformingRecap - Frequency Counter10Project - Student Records
Project OverviewAdd Student5Enumerable Powerhouse
Select and RejectChaining MapReduce / Injectcount, all?, any?, none?group_by and partitionsort_by, min_by, max_byRecap - Data Pipeline8Advanced Decision Making
Case with Classes & RegexMulti-value whenTernary OperatorInline if / unlessRecap - Grade Classifier