From: daz Date: 2005-09-03T12:46:26+09:00 Subject: Re: beginners YAML question Adam Shelly wrote: > Thanks, > That fixed the load error, but there is still a problem > with the to_yaml routine. The additional @size parameter > never gets written to the YAML string. > > require 'yaml' > > class Box < Array > def initialize size > @size = size > end > def size > @size > end > end > > > box = Box.new(2) > print "ERROR: Box, #{box.size}!=2" unless box.size == 2 > box2 = YAML::load(box.to_yaml) > print "ERROR: Box2, #{box2.size}!=2" unless box2.size == 2 > p box.to_yaml > > > ERROR: Box2, !=2 > --- !ruby/array:Box [] > > > Any ideas? > -Adam In short, @size is an attribute of Box ... but you're using the inherited Array#to_yaml to serialise your object. Some pointers ... 1) By defining an initialize method in Box, you /override/ the Array initialize - so, an empty Array is allocated. To fix this, you need to call "super" (see 2) 2) Array already has a size attribute, so this works: require 'yaml' class Box < Array def initialize(*args, &block) super end end box = Box.new(3) {|x| 2*x} box2 = YAML::load(box.to_yaml) print "ERROR: box2 != box" unless box2 == box puts box.to_yaml #-> --- !ruby/array:Box #-> - 0 #-> - 2 #-> - 4 3) Note that if you /don't/ inherit from Array, to_yaml saves as a !ruby/object:Box along with all current instance variables of Box. require 'yaml' class Box def initialize(*args) @high, @wide = *args end end box = Box.new(4,7) puts box.to_yaml box2 = YAML::load(box.to_yaml) puts box2.to_yaml #-> --- !ruby/object:Box #-> high: 4 #-> wide: 7 #-> --- !ruby/object:Box #-> high: 4 #-> wide: 7 # Note: I left out the "box2 != box" comparison # because Boxes are not comparable until you # define the mechanism. 4) If you want Box to behave like an Array but with attributes of its own, there are ways. Ask again (giving details) if you need help with that or any other aspect. Cheers, daz