Brian Buckley wrote: > Hello all, > > I have an immutable class Foo (once a foo object is created its state > is fixed). Foo objects have a bunch of attributes so their yaml > strings are fairly long. > > There is a small set of standard, frequently used foo objects and I > have defined these as constants right in the class (newed and set > each attribute for Foo::FOO1, Foo::FOO2, ... etc.). > > When I YAML one of these standard foos to the database and back, it > seems inefficient to create and send a big long yaml string describing > each attribute and then on retrieval to create a whole new Foo object > when all I really want is to look up an already-made constant. > > Is there a good solution to making the yaml-ing of constants efficient? > > Thanks! > > --Brian Buckley > > foo = Foo:FOO1 > data = foo.to_yaml # the yaml string here is unnecessarily long > foo = YAML::load(data) # and now after retrieval we have an > additional foo object when we really only need the one original > constant The only problem with the following (I think) is that you have to pass the constant name in when you instantiate. Note that the object ID of the object returned by YAML.load is the same as the original, so it's actually the same object. require 'yaml' class Foo attr_reader :name def initialize name @name = name end def is_complex_yaml? false end def to_yaml( opts = {} ) YAML::quick_emit( nil, opts ) { |out| out << "!ruby/foo " self.name.to_yaml( :Emitter => out ) } end end YAML.add_ruby_type(/^foo/) do |type, val| subtype, subclass = YAML.read_type_class(type, Foo) val.split(/::/).inject(Object) { |p, n| p.const_get(n)} end foo = FOO1 = Foo.new("FOO1") p foo data = foo.to_yaml puts(data) foo = YAML.load(data) p foo __END__ #<Foo:0xb7bff274 @name="FOO1"> --- !ruby/foo FOO1 #<Foo:0xb7bff274 @name="FOO1"> -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407