Justin Collins
2/17/2009 8:33:00 PM
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