Reputation: 703
Say that I open a file in Ruby like this:
f = File.open('diagram.txt', 'r')
Right now, in order to close and delete that file I have this code:
begin
f = File.open('diagram.txt', 'r')
ensure
if !f.nil? && File.exist?(f)
f.close unless f.closed?
File.delete(f)
end
end
I found this code to be too complicated, and the File.exist?(f)
would fail if the f is closed already. So, what is the correct approach to avoid the closing and deleting of the file raising exceptions?
Note: I know that passing a block to File.open will close the file directly, however, I am looking for the general approach of closing and deleting.
Upvotes: 18
Views: 27899
Reputation: 75478
Just delete the file after closing without referring to the object.
begin
f = File.open('diagram.txt', 'r')
# Do something with file.
ensure
f.close unless f.nil? || f.closed?
File.delete('diagram.txt') if File.exist? 'diagram.txt'
end
Upvotes: 15
Reputation: 84343
Since your diagram.txt file is not guaranteed to exist in your example code, your bigger problem is handling the Errno::ENOENT exception. You can Call File#open in a self-closing block, and then use rescue to handle the exception if you try to open or delete a missing file. For example:
begin
File.open('diagram.txt', 'r') do |f|
# do something with file
File.delete(f)
end
rescue Errno::ENOENT
end
Upvotes: 19
Reputation: 48348
Depending on your specific situation, it might be possible to use Tempfile.create
. From the docs:
If a block is given, then a File object will be constructed, and the block is invoked with the object as the argument. The File object will be automatically closed and the temporally file is removed after the block terminates. The call returns the value of the block.
(Emphasis mine)
Usage:
require 'tempfile'
Tempfile.create('diagram.txt') do |f|
# Do something with the file
end
Upvotes: 3