Ruby:析构函数?

Joe*_*ann 24 ruby destructor

我需要偶尔在缓存目录中使用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
Run Code Online (Sandbox Code Playgroud)


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
Run Code Online (Sandbox Code Playgroud)

  • AFAIK(我承认我没有很多经验)这不起作用,因为procs保持对它们所定义的上下文的"self"的隐式引用 - 在这种情况下是相同的对象终结器附加到,因此终结器将阻止对象被收集. (4认同)
  • http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/ (4认同)
  • 这真是一个非常重要的特征,缺少,Matz先生,我们需要析构函数!:) (3认同)

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
Run Code Online (Sandbox Code Playgroud)

块完成执行后,图像被销毁.只需启动一个块,在里面进行所有图像处理,然后让图像自行破坏.这类似于以下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
Run Code Online (Sandbox Code Playgroud)