From: Justin Collins Date: 2009-02-18T05:57:19+09:00 Subject: Re: Marshal.dump fails on extended OpenStruct Justin Collins wrote: > 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') > I give up. I don't know why the formatting is all weird. -Justin