I've recently started programming in Ruby, and I am looking at exception handling.
I was wondering if ensure
was the Ruby equivalent of finally
in C#? Should I have:
file = File.open("myFile.txt", "w")
begin
file << "#{content} \n"
rescue
#handle the error here
ensure
file.close unless file.nil?
end
or should I do this?
#store the file
file = File.open("myFile.txt", "w")
begin
file << "#{content} \n"
file.close
rescue
#handle the error here
ensure
file.close unless file.nil?
end
Does ensure
get called no matter what, even if an exception isn't raised?
This question is related to
ruby-on-rails
ruby
exception
exception-handling
error-handling
Yes, ensure
ENSURES it is run every time, so you don't need the file.close
in the begin
block.
By the way, a good way to test is to do:
begin
# Raise an error here
raise "Error!!"
rescue
#handle the error here
ensure
p "=========inside ensure block"
end
You can test to see if "=========inside ensure block" will be printed out when there is an exception.
Then you can comment out the statement that raises the error and see if the ensure
statement is executed by seeing if anything gets printed out.
Yes, ensure
like finally
guarantees that the block will be executed. This is very useful for making sure that critical resources are protected e.g. closing a file handle on error, or releasing a mutex.
Yes, ensure
is called in any circumstances. For more information see "Exceptions, Catch, and Throw" of the Programming Ruby book and search for "ensure".
If you want to ensure a file is closed you should use the block form of File.open
:
File.open("myFile.txt", "w") do |file|
begin
file << "#{content} \n"
rescue
#handle the error here
end
end
This is why we need ensure
:
def hoge
begin
raise
rescue
raise # raise again
ensure
puts 'ensure' # will be executed
end
puts 'end of func' # never be executed
end
FYI, even if an exception is re-raised in the rescue
section, the ensure
block will be executed before the code execution continues to the next exception handler. For instance:
begin
raise "Error!!"
rescue
puts "test1"
raise # Reraise exception
ensure
puts "Ensure block"
end
Source: Stackoverflow.com