Errors in Ruby
In Ruby, it’s idiomatic to communicate errors via exceptions, which is different from the explicit error return values used in some other languages. Ruby’s approach makes it easy to handle errors using language constructs like begin
, rescue
, and ensure
.
# In Ruby, we don't need to explicitly import modules for basic functionality
# We define a method that may raise an exception
def f(arg)
if arg == 42
# Instead of returning an error, we raise an exception
raise ArgumentError, "can't work with 42"
end
# If no exception is raised, we simply return the result
arg + 3
end
# We can define custom exception classes
class OutOfTeaError < StandardError; end
class PowerError < StandardError; end
def make_tea(arg)
case arg
when 2
raise OutOfTeaError, "no more tea available"
when 4
# We can raise an exception with a nested cause
raise PowerError, "making tea: can't boil water"
end
# If no exception is raised, the method implicitly returns nil
end
# Main execution
[7, 42].each do |i|
# It's common to use a begin/rescue block for error handling
begin
result = f(i)
puts "f worked: #{result}"
rescue ArgumentError => e
puts "f failed: #{e.message}"
end
end
5.times do |i|
begin
make_tea(i)
puts "Tea is ready!"
rescue OutOfTeaError
puts "We should buy new tea!"
rescue PowerError
puts "Now it is dark."
rescue StandardError => e
puts "unknown error: #{e.message}"
end
end
When you run this Ruby script, you’ll get output similar to this:
f worked: 10
f failed: can't work with 42
Tea is ready!
Tea is ready!
We should buy new tea!
Tea is ready!
Now it is dark.
In Ruby, we use exceptions for error handling. The raise
keyword is used to throw an exception, and rescue
is used to catch and handle exceptions. This is similar to try
/catch
in many other languages.
Ruby doesn’t have a built-in way to wrap errors like Go’s fmt.Errorf
with %w
, but you can achieve similar functionality by setting the cause
of an exception when you raise it, or by using custom exception classes that contain additional context.
The StandardError
class is the default superclass for all standard errors. You can create custom error classes by inheriting from StandardError
or any of its subclasses.
Ruby’s case
statement is used here as an equivalent to Go’s if
/else if
chain in the makeTea
function.
Remember that in Ruby, the last evaluated expression in a method is implicitly returned, so we don’t need explicit return
statements in many cases.
This example demonstrates how Ruby’s exception handling mechanism can be used to achieve similar error handling patterns as in Go, while following Ruby’s idiomatic practices.