On Tue, Feb 20, 2007 at 08:48:07AM +0900, Raymond O’connor wrote:
I’m trying to write a logger class. I open the file in the initialize
method. Is there a destructor that I can override to close the file, or
can I just assume the file is closed automatically?
Am I going about this all wrong, and should instead just open and close
the file each time I write to it?
Ruby has no destructors (there are these things called finalizers, but
in general it’s best to pretend they don’t exist).
The usual idiom for a file (or any resource that needs to be released)
is:
File.open(path, read_or_write) do |file|
use file
end # The file will be closed
The way to implement something like that is to define a method like:
def open
resource = Resource.new
begin
yield( resource ) # pass the resource into the block
ensure # code in an ensure block always gets run, even if an exception
# is raised
resource.release
end
end
open { |res| res.use }
Unfortunately a logger doesn’t work well with this idiom.
You could provide an explicit teardown method for the logger and call it
when the program ends, or use the block based idiom:
Logger.new do |logger|
… whole program …
end
but that strikes me as awkward. The other option is the at_exit method.
It gets supplied a block to be run when the program exits, so in your
initalize you could do:
def initialize
@file = File.open(path, “w”)
at_exit { @file.close }
end
Finally, on a parting note, are you aware that ruby’s standard library
has a logger? Just require ‘logger’.