我需要偶尔在缓存目录中使用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)
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)