如何从marshal转储中排除实例变量

我的对象包含一个实例变量,该变量指向其他几个属性中的File对象。 因为这个Marshal不能序列化它。 如何编写一个定制的dump方法,以便只排除该实例变量?

 class Area attr_accessor :area attr_reader :several_other_attributes ........ def initialize(name) @area = name @several_other_attributes = .... @log = File.open( 'test.log', 'w') end end 

您可以非常轻松地编写marshal_dumpmarshal_load方法,该方法可以marshal_dump marshal_load除指定数量的实例变量之外的所有实例。 以下是您可以做的相当通用的示例:

 class MarshalTest attr_reader :foo, :bar, :baz, :t UNMARSHALED_VARIABLES = [:@foo, :@bar] def initialize(foo = nil, bar = nil, baz = nil, t = nil) @foo = foo @bar = bar @baz = baz @t = t end def marshal_dump instance_variables.reject{|m| UNMARSHALED_VARIABLES.include? m}.inject({}) do |vars, attr| vars[attr] = instance_variable_get(attr) vars end end def marshal_load(vars) vars.each do |attr, value| instance_variable_set(attr, value) unless UNMARSHALED_VARIABLES.include?(attr) end end end 

用法示例:

 1.9.3-p550 :026 > m = MarshalTest.new(1, 2, 3, 4) => # 1.9.3-p550 :027 > m.foo => 1 1.9.3-p550 :028 > m.bar => 2 1.9.3-p550 :029 > m.baz => 3 1.9.3-p550 :030 > mt => 4 1.9.3-p550 :031 > s = Marshal.dump(m) => "\x04\bU:\x10MarshalTest{\a:\t@bazi\b:\a@ti\t" 1.9.3-p550 :032 > n = Marshal.load(s) => # 1.9.3-p550 :033 > n.foo => nil 1.9.3-p550 :034 > n.bar => nil 1.9.3-p550 :035 > n.baz => 3 1.9.3-p550 :036 > nt => 4 

如您所见,在编组/解组中忽略了实例变量foobar