From: Justin Collins Date: 2009-02-18T05:52:19+09:00 Subject: Re: Marshal.dump fails on extended OpenStruct Justin Collins wrote: > synergism wrote: >> If I subclass OpenStruct and extend the subclass, I cannot >> Marshal.dump it. This is apparently because ostruct.rb has its own >> custom marshal_dump / marshal_load that only cares about what's in >> @table: >> >> def marshal_dump >> @table >> end >> def marshal_load(x) >> @table = x >> @table.each_key{|key| new_ostruct_member(key)} >> end >> >> Is there no way to fix this in ostruct.rb to allow my 'bad' example >> below to work? >> >> require 'pp' >> require 'ostruct' >> >> case ARGV.first >> when /bad/i,nil >> class C < OpenStruct >> def initialize >> super() >> @var=123 >> end >> end >> when /good/i >> class C >> def initialize >> @struct=OpenStruct.new >> @var=123 >> end >> >> def method_missing method,*args,&block >> @struct.send method,*args,&block >> end >> end >> end >> >> c=C.new >> c.a=:a >> pp c >> puts 'c.a=%s ' % c.a >> puts 'c var=%s' % c.instance_variable_get('@var') >> x=Marshal.load(Marshal.dump(c)) >> >> pp x >> puts 'x.a=%s ' % x.a >> puts 'x var=%s' % x.instance_variable_get('@var') >> >> > > Let me try that again: require 'ostruct' require 'pp' class C < OpenStruct def initialize *args super @var = 123 end def marshal_dump [@table, Hash[self.instance_variables.map { |v| [v, self.instance_variable_get("#{v}")] }]] end def marshal_load x @table = x[0] @table.each_key{|key| new_ostruct_member(key)} x[1].each do |k,v| self.instance_variable_set("#{k}", v) unless k.to_sym == :table end end end c=C.new c.a=:a pp c puts 'c.a=%s ' % c.a puts 'c var=%s' % c.instance_variable_get('@var') x=Marshal.load(Marshal.dump(c)) pp x puts 'x.a=%s ' % x.a puts 'x var=%s' % x.instance_variable_get('@var')