Title here
Summary here
# Defer is used to ensure that a function call is performed later in a program's
# execution, usually for purposes of cleanup. In Crystal, we use `ensure` blocks
# for similar purposes.
require "file"
# Suppose we wanted to create a file, write to it,
# and then close when we're done. Here's how we could
# do that with `ensure`.
def main
# Immediately after getting a file object with
# `File.new`, we put the closing of that file
# in an `ensure` block. This will be executed at the end
# of the enclosing function (`main`), after
# `write_file` has finished.
f = create_file("/tmp/defer.txt")
begin
write_file(f)
ensure
close_file(f)
end
end
def create_file(p : String) : File
puts "creating"
File.new(p, "w")
rescue ex
puts "Error: #{ex.message}"
exit(1)
end
def write_file(f : File)
puts "writing"
f.puts "data"
end
# It's important to check for errors when closing a
# file, even in an ensure block.
def close_file(f : File)
puts "closing"
f.close
rescue ex
STDERR.puts "error: #{ex.message}"
exit(1)
end
main
Running the program confirms that the file is closed after being written.
$ crystal run defer.cr
creating
writing
closing
In Crystal, we use ensure
blocks to achieve similar functionality to Go’s defer
. The ensure
block guarantees that the code within it will be executed when the enclosing method exits, regardless of whether an exception was raised or not.
The structure of the program remains similar, but we’ve made a few Crystal-specific adjustments:
require "file"
instead of importing specific packages.main
method and call it at the end of the file, as Crystal doesn’t have a special main
function.defer
, we use a begin
/ensure
block to ensure the file is closed.rescue
) instead of explicitly checking for errors.File.new
instead of os.Create
to create a file.STDERR.puts
instead of fmt.Fprintf(os.Stderr, ...)
for error output.This Crystal code provides the same functionality as the original Go code, ensuring that resources are properly cleaned up using ensure
blocks.