Run a Method on deletion of an Object

六月ゝ 毕业季﹏ 提交于 2019-12-21 23:09:11

问题


I am learning ruby and haven't found a way to override an equivalent object.delete function:

This is how I am doing it:

    class Foo
        @@no_foo=0
        def initialize
            @@no_foo+=1
        end
        def delete
            #class specific cleanup...
            @@no_foo-=1
        end
        def Foo.no_foo
            return "#@@no_foo"
        end
    end

    def delete(obj)
        #object independent cleanup...
        obj.delete
        return nil
    end

    foo1 = Foo.new
    foo2 = Foo.new

    puts Foo.no_foo

    puts foo2
    foo2 = delete(foo2)
    puts foo2

    puts Foo.no_foo

As you can see, this is a bit of a hacky way of going about things... is there an easier way to go about this?
Basically I would like to make my objects unaccessible in the same call as decrementing the total counter for that class. I couldn't find a method that gets called when setting a variable(pointer to object) to nil.

I found no way to delete an object.


回答1:


Even though ruby doesn't have explicit destructors, it has support for finalizers. Finalizer is a piece of code that gets called when your object is garbage-collected.

class Foo
  @@no_foo = 0

  def initialize
    @@no_foo += 1
    ObjectSpace.define_finalizer(self, Foo.method(:delete))
  end

  def self.delete id # also this argument seems to be necessary
    @@no_foo -= 1
  end

  def self.no_foo
    @@no_foo
  end
end

Seems that you won't be able to do instance-specific cleanup in the finalizer. It has to be completely detached from the instance in order to work correctly. Here are answer that might also help you: answer, answer.




回答2:


as per the link provided by @RubyLovely: WeakRef.
I put together the following sample class:

require 'weakref'
  class Foo
    #block to excecute on GC.start...
    FINALIZER = lambda { |object_id| p "finalizing %d" % object_id; @@no_foo -=1 }

    @@no_foo=0
    def initialize
        @@no_foo+=1
        #Initialising the finalizer...
        ObjectSpace.define_finalizer(self, FINALIZER)
    end

    def Foo.no_foo
        @@no_foo
    end
end

foo = Foo.new
foo = WeakRef.new(foo)
puts Foo.no_foo

GC.start

puts Foo.no_foo


来源:https://stackoverflow.com/questions/16794153/run-a-method-on-deletion-of-an-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!