ObjectSpace.each_object返回的枚举器是按对象创建时间排序的吗?

时间:2015-11-05 18:56:16

标签: ruby

ObjectSpace.each_object(ExampleClass)返回ExampleClass的所有实例的枚举器。这个枚举器是否保证按对象创建时间排序?

2 个答案:

答案 0 :(得分:2)

我认为更常规的做法是这样的:

class A
  attr_reader :instance_id

  def initialize
    new_id = (self.class.last_instance_id || self.class.first_id-1) + 1
    self.class.instance_variable_set(:@last_instance_id, new_id)
    @instance_id = new_id 
  end

  def self.set_first_id(first_id)
    @first_id = id
  end

  singleton_class.send(:attr_accessor, :first_id)
  singleton_class.send(:attr_reader, :last_instance_id)
end

A.first_id = 0       
a0 = A.new         #=> #<A:0x007fe2bb8c3de0 @instance_id=0> 
a0.instance_id     #=> 0

a1 = A.new         #=> #<A:0x007fe2bb8b87d8 @instance_id=1> 
a1.instance_id     #=> 1 

a2 = A.new         #=> #<A:0x007fe2bb8aa2c8 @instance_id=2> 
a2.instance_id     #=> 2 

A.last_instance_id #=> 2

答案 1 :(得分:1)

从非常小的测试看来似乎是这种情况,尽管如上所述它可能是基于实现的,我不会在生产环境中推荐它但是

class R; end
m = 1000.times.map {R.new}
os = ObjectSpace.each_object(R).to_a
m.reverse.each_with_index.all? {|e,i| e === os[i]}
#=> true

使用ObjectSpace的另一个问题是垃圾回收。一旦一个物体超出范围,GC就会例行清理它们,这样你可能会在较早的物体之前丢失一个物体,因此我不会建议这个过程作为保留你想要的“id”的准确方法。