From: Justin Collins Date: 2009-02-18T05:32:52+09:00 Subject: Re: Marshal.dump fails on extended OpenStruct 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') > > You could just write new marshal_dump and marshal_load methods: 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') -Justin