tags:

views:

58

answers:

4

Let´s say I have a logger class that has an attribute pointing to an open file. This file should be open until this class is no longer used. Something like:

class MyLogger
  attr_accessor :log_file
  def initialize
    @log_file = File.new('my_log_file_name.log','w')
  end

  def finalize(id)
    @log_file.close
  end
end

How can I ensure that when I will no longer use this instance, the file handle will be closed? I´ve tried this but with no effect:

l = MyLogger.new
l = nil
ObjectSpace.garbage_collect

After this, if I try to delete the file it will throw an error stating that the file is in use.

A: 

If you need to free resources from an object, do it explicitly.

I found this sample source code helpful.

Joe
+1  A: 

Just close tha file handle through a method call. It does not really make sense to do it any other way, especially waiting for the garbage collector. If you know hen you are done with it do your cleanup at that point.

willcodejavaforfood
You could have a method like `File.open`, which takes a block and handles opening and closing the file handle for you.
Chuck
A: 

Since the Ruby garbage collector runs at unpredictable times, it is impossible to know when the destructor code will run. It may be better if you just open and close the file every time within a single method call.

edgerunner
A: 

Do you need to have the log file open all the time? You could do an open/write/close when you want to log something and hide that logic inside a MyLogger method. There is some overhead to opening and closing a file all the time but that overhead is probably inconsequential unless you're logging every iteration in a loop.

If the outside world is directly accessing log_file then you have bigger problems on your hands than manually closing it. If there is already a large code base that is messing with log_file directly then you could replace it with an little object that does the necessary open/write/close sequence when some writes to it.

mu is too short