在Ruby中删除一个对象 [英] Deleting an object in Ruby
问题描述
假设我有以下班级:
class Vehicle
@@ total_vehicles = 0
@@ all_instances = Array.new
def初始化
@@ total_vehicles + = 1
@@ all_instances<< self
end
def total_vehicles #returns'alive'总数'
return @@ total_vehicles
end
def all_vehicles #returns所有Vehicle对象的数组
return @@ all_instances
end
end
现在保持 @@ total_vehicles
和 @@ all_instances
最新且正确,我想确保它们分别正确递减和更新,当其中一个对象被垃圾收集时。但是这里发生了什么:
v = Vehicle.new
Vehicle.total_vehicles#=> 1
v = nil#现在没有引用Vehicle实例
ObjectSpace.garbage_collect#实例垃圾收集
Vehicle.total_vehicles#=> 1没有!
那么我可以为每个Vehicle类实例添加一个终结器Proc,当调用对象的垃圾收集,将被调用。但根据文档,在Vehicle实例被销毁之后, 我怎样才能获得相当于析构函数的方法(来自C ++),在获取垃圾回收之前,它将按顺序获得Vehicle实例的事务? PS 现在,它们将永远不会被垃圾收集,因为您在 如果您运行此代码,您会看到它作品,除了有一辆车没有收集垃圾。我不确定这是为什么。 您的 最后,如果您真的想维护现有车辆列表,您需要存储他们的ID并使用 Let's say I have the following class: Now to keep Well I could add a finalizer Proc to each instance of the Vehicle class that, when called upon the object's garbage collection, would be called. But according to the documentation, How can I have the equivalent of a destructor method (from C++) that will get a Vehicle instance's affairs in order, as it were, before getting garbage-collected? P.S.
Right now, they will never be garbage collected, as you are holding a reference in If you run this code, you will see that it "works", except that there remains one Vehicle that is not garbage collected. I'm not sure why that is. Your Finally, if you really want to maintain a list of existing Vehicles, you need to store their ID and use
这篇关于在Ruby中删除一个对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! ObjectSpace.define_finalizer(v,someProc)
会调用someProc - 这意味着我不能使用 self
或 self.class
在那里(因为没有类,因为没有对象!)我可以有proc在Vehicle类上调用一个公共访问器方法,但是这会带走只能通过类及其实例访问的类变量的目的 - >本质上将类变量转换为gvars。
ObjectSpace#count_objects
并不是一个可行的选择,因为即使是Ruby文档也在前面。
@@ all_instances
中持有引用。您可以使用终结器来获得您想要的结果:
class Vehicle
class<< self
attr_accessor:count
def finalize(id)
@count - = 1
end
def all#返回所有Vehicle对象的数组
ObjectSpace.each_object(Vehicle).to_a
end
end
Vehicle.count || = 0
def初始化
Vehicle.count + = 1
ObjectSpace.define_finalizer(self,Vehicle.method(:finalize))
end
end
100.times {Vehicle.new}
p Vehicle.count#=> 100
ObjectSpace.garbage_collect
p Vehicle.count#=> 1,不知道为什么
p Vehicle.all#=> [#< Vehicle:0x0000010208e730>]
count
方法也可以通过返回 ObjectSpace.each_object(Vehicle).count
ObjectSpace._id2ref
:
require'set '
class Vehicle
class<< self
def finalize(id)
@ ids.delete(id)
end
def register(obj)
@ids || = Set。新的
@ids<< obj.object_id
ObjectSpace.define_finalizer(obj,method(:finalize))
end
def all#返回一个包含所有Vehicle对象的数组
@ ids.map {| ID | ObjectSpace._id2ref(id)}
end
$ b $ def def count
@ ids.size
end
end
def initialize
Vehicle.register(self)
end
end
class Vehicle
@@total_vehicles = 0
@@all_instances = Array.new
def initialize
@@total_vehicles += 1
@@all_instances << self
end
def total_vehicles #returns total number of Vehicles 'alive'
return @@total_vehicles
end
def all_vehicles #returns an array of all Vehicle objects
return @@all_instances
end
end
@@total_vehicles
and @@all_instances
up-to-date and correct, I want to make sure that they are correctly decremented and updated, respectively, when one of those objects is garbage collected. But here is what happens:v = Vehicle.new
Vehicle.total_vehicles # => 1
v = nil #no references to Vehicle instance now
ObjectSpace.garbage_collect #instance garbage collected
Vehicle.total_vehicles # => 1 Nope!
ObjectSpace.define_finalizer(v,someProc)
would call someProc after the Vehicle instance is destroyed - meaning I cannot use self
or self.class
in there (since there would be no class, as there is no object!) I could have the proc call a public accessor method on the Vehicle class, but that takes away the purpose of class variables being accessible only to the class and its instances -> essentially turning the class variables into gvars.ObjectSpace#count_objects
is no a viable option, as even the Ruby docs are up front about.@@all_instances
. You could use a finalizer to get the result you want:class Vehicle
class << self
attr_accessor :count
def finalize(id)
@count -= 1
end
def all #returns an array of all Vehicle objects
ObjectSpace.each_object(Vehicle).to_a
end
end
Vehicle.count ||= 0
def initialize
Vehicle.count += 1
ObjectSpace.define_finalizer(self, Vehicle.method(:finalize))
end
end
100.times{Vehicle.new}
p Vehicle.count # => 100
ObjectSpace.garbage_collect
p Vehicle.count # => 1, not sure why
p Vehicle.all # => [#<Vehicle:0x0000010208e730>]
count
method could be also defined more simply by returning ObjectSpace.each_object(Vehicle).count
ObjectSpace._id2ref
:require 'set'
class Vehicle
class << self
def finalize(id)
@ids.delete(id)
end
def register(obj)
@ids ||= Set.new
@ids << obj.object_id
ObjectSpace.define_finalizer(obj, method(:finalize))
end
def all #returns an array of all Vehicle objects
@ids.map{|id| ObjectSpace._id2ref(id)}
end
def count
@ids.size
end
end
def initialize
Vehicle.register(self)
end
end