Defer in Ruby
Our example demonstrates the use of ensure in Ruby, which is similar to defer in other languages. It’s used to ensure that a piece of code is executed, usually for cleanup purposes, regardless of whether an exception is raised or not.
require 'fileutils'
def main
# Immediately after getting a file object with
# create_file, we use a begin/ensure block to ensure
# the file is closed after we're done writing to it.
begin
f = create_file("/tmp/ensure.txt")
write_file(f)
ensure
close_file(f)
end
end
def create_file(path)
puts "creating"
File.new(path, "w")
rescue StandardError => e
puts "Error: #{e.message}"
exit(1)
end
def write_file(file)
puts "writing"
file.puts "data"
end
# It's important to check for errors when closing a
# file, even in an ensure block.
def close_file(file)
puts "closing"
file.close
rescue StandardError => e
warn "Error: #{e.message}"
exit(1)
end
mainRunning the program confirms that the file is closed after being written.
$ ruby ensure.rb
creating
writing
closingIn this Ruby version:
We use a
begin/ensureblock in themainmethod to ensure thatclose_fileis called regardless of what happens in thebeginblock.Instead of
panic, we use Ruby’s exception handling withrescueto catch and handle errors.The
createFilefunction is renamed tocreate_fileto follow Ruby naming conventions.We use
File.newinstead ofos.Createto create a new file.In
close_file, we usewarnto print error messages to STDERR.We don’t need to explicitly return the file object in
create_fileas Ruby automatically returns the last evaluated expression.
This example demonstrates how Ruby’s ensure can be used to handle cleanup operations, similar to defer in other languages.
Comments powered by Disqus