Bugs item #3698, was opened at 2006-03-01 19:10
You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=3698&group_id=426

Category: Standard Library
Group: v1.0 (example)
Status: Open
Resolution: None
Priority: 3
Submitted By: Hannes Wyss (hwyss)
Assigned to: Nobody (None)
Summary: In a highly dynamic ObjectSpace (loads of created and collected objects) YAML creates erroneous anchors/references

Initial Comment:
Here is a script that demonstrates the problem:

#!/usr/bin/env ruby

require 'yaml'

class Foo
  def collection
    ## simulate a cached environment where Object are loaded on demand
    @collection ||= [Object.new]
  end
  def to_yaml(opts={})
    res = YAML::quick_emit( self.object_id, opts ) { |out|
      out.map( taguri ) { |map|
        ## create a temporary Array with relevant data - in the real-world
        ## case this is not a dup, but I can reproduce the problem much faster this way
        map.add('collection', collection.collect { |o| o.dup })
      }
    }
    GC.start
    res
  end
end

foos = []
dump = ''
until(/id/.match(dump = foos.to_yaml))
  foos.push(Foo.new)
end
puts "Id-Collision in YAML after #{foos.size} attempts"
#puts dump


On a PowerBook with 1G ram:
hwyss@lapdog ~ $ ruby -v
ruby 1.8.4 (2006-02-24) [powerpc-linux]
hwyss@lapdog ~ $ ruby collision.rb
Id-Collision in YAML after 3 attempts
---
- !ruby/object:Foo
  collection:
  - &id001 !ruby/object {}

- !ruby/object:Foo
  collection:
  - !ruby/object {}

- !ruby/object:Foo
  collection:
  - *id001


On a i686 with 2 G ram:
ywesee@HotPower ~ $ ruby -v
ruby 1.8.4 (2006-02-24) [i686-linux]
ywesee@HotPower ~ $ ruby collision.rb
Id-Collision in YAML after 74 attempts


An attempt at working around the Problem using ObjectSpace#define_finalizer is attached. However I am not sure
a) whether this really is unexpected Behavior
b) if the suggested workaround is the best available
c) whether referencing the emitter in the finalizer-proc will prevent it from being garbage collected 

TIA for your help

Hannes

----------------------------------------------------------------------

You can respond by visiting: 
http://rubyforge.org/tracker/?func=detail&atid=1698&aid=3698&group_id=426