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.
13 Answers
Handling the Errno::ENOENT Exception
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 2Why not just delete the file after closing and not depending from the object but from the filename itself?
begin f = File.open('diagram.txt', 'r') ensure f.close unless f.nil? or f.closed? File.delete('diagram.txt') if File.exists? 'diagram.txt' end 1Depending 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