问题
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