我需要偶尔在缓存目录中使用rmagick创建图像.
然后快速摆脱它们而不丢失视图,我想删除图像文件,同时我的图像类的Ruby实例被破坏或进入垃圾收集.
我必须覆盖什么ClassMethod来为析构函数提供代码?
Su *_*ang 25
@ edgerunner的解决方案几乎奏效了.基本上,您不能创建一个闭包代替define_finalizer调用,因为它捕获了当前的绑定self.在Ruby 1.8中,似乎你不能使用从绑定到任何一个的方法proc转换(使用to_proc)的任何对象self.要使其工作,您需要一个proc不捕获您正在定义终结器的对象的对象.
class A
  FINALIZER = lambda { |object_id| p "finalizing %d" % object_id }
  def initialize
    ObjectSpace.define_finalizer(self, self.class.method(:finalize))  # Works in both 1.9.3 and 1.8
    #ObjectSpace.define_finalizer(self, FINALIZER)                    # Works in both
    #ObjectSpace.define_finalizer(self, method(:finalize))            # Works in 1.9.3
  end
  def self.finalize(object_id)
    p "finalizing %d" % object_id
  end
  def finalize(object_id)
    p "finalizing %d" % object_id
  end
end
a = A.new
a = nil
GC.start
edg*_*ner 21
您可以ObjectSpace.define_finalizer在创建图像文件时使用它,并在垃圾人收集时调用它.注意不要在你的proc中引用对象本身,否则垃圾人不会收集它.(不会拿起那些活着和踢的东西)
class MyObject
  def generate_image
    image = ImageMagick.do_some_magick
    ObjectSpace.define_finalizer(self, proc { image.self_destruct! })
  end
end
nur*_*tin 11
GC怪癖很好看,但为什么不能根据现有的语言语法正确释放资源呢?
让我澄清一下.
class ImageDoer
  def do_thing(&block)
    image= ImageMagick.open_the_image # creates resource
    begin
      yield image # yield execution to block
    rescue
      # handle exception
    ensure
      image.destruct_sequence # definitely deallocates resource
    end
  end
end
doer= ImageDoer.new
doer.do_thing do |image|
  do_stuff_with_image # destruct sequence called if this throws
end # destruct_sequence called if execution reaches this point
块完成执行后,图像被销毁.只需启动一个块,在里面进行所有图像处理,然后让图像自行破坏.这类似于以下C++示例:
struct Image
{
  Image(){ /* open the image */ }
  void do_thing(){ /* do stuff with image */ }
  ~Image(){ /* destruct sequence */ }
};
int main()
{
  Image img;
  img.do_thing(); // if do_thing throws, img goes out of scope and ~Image() is called
} // special function ~Image() called automatically here