From: Robert Klemme Date: 2006-12-27T01:35:09+09:00 Subject: Re: YAML problem with serializing of nested object structures --------------040209020305050109040306 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 26.12.2006 15:11, Kjetil Orbekk wrote: > Hi! > > I'm making a graph tool, and i have some problem with the > serialization of my graphs. The problem comes when i try to load a > graph i earlier serialized with YAML. In the objects i serialize, I > have two instance variables (arrays, as below) that contain some other > objects of similar type (also serialized). I managed to reproduce the > problem with a simpler object structure below. To me, this seems very > wierd, especially since it saves some data and breaks it when > loading. Could it be a bug, or am I doing something wrong here? > > ruby --version is "1.8.4 (2005-12-24) [i486-linux]". My operating > system is Debian GNU/Linux 4.0. First of all, there does not seem to be an issue with general recursive structures: $ irb -r yaml irb(main):001:0> a=[1] => [1] irb(main):002:0> b=[2,a] => [2, [1]] irb(main):003:0> a << b => [1, [2, [...]]] irb(main):004:0> b => [2, [1, [...]]] irb(main):005:0> str = a.to_yaml => "--- &id001 \n- 1\n- - 2\n - *id001\n" irb(main):007:0> c = YAML.load str => [1, [2, [...]]] irb(main):008:0> c[1] => [2, [1, [...]]] I changed your code a bit (attached) but with no new results. It seems, you actually hit a bug in YAML. Marshal does not seem to have this problem (see last output). So, if the output needs not be readable then this is definitively an alternative - and it's also faster IIRC. Kind regards robert --------------040209020305050109040306 Content-Type: text/plain; name="ya.rb" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ya.rb" require "yaml" require 'pp' # Test class with two instance variables to hold arrays with similar # objects class Test attr_accessor :c1, :c2 def initialize(c1=[], c2=[]) @c1, @c2 = c1, c2 end end a = Test.new b = Test.new([a],[Test.new]) a.c1 << b a.c2 << b # The problem comes when saving the whole thing as an array ary = [a, b] puts "Original:" pp ary puts "" yaml1 = YAML.dump(ary) # +ary_from_yaml[0]+ looses its c2 even though it's clearly in the YAML output ary_from_yaml = YAML.load(yaml1) puts "Copy:" pp ary_from_yaml puts "" yaml2 = YAML.dump(ary_from_yaml) print "YAML 1\n" + yaml1 + "\n\n" print "YAML 2\n" + yaml2 + "\n\n" p "YAML1", yaml1 p "YAML2", yaml2 print "YAML 1 length: #{yaml1.length} \tYAML 2 length: #{yaml2.length}\n" pp Marshal.load(Marshal.dump(ary)) --------------040209020305050109040306--