diff --git a/lib/recursive_open_struct.rb b/lib/recursive_open_struct.rb index 184e5ef..debbeab 100644 --- a/lib/recursive_open_struct.rb +++ b/lib/recursive_open_struct.rb @@ -39,6 +39,16 @@ def initialize(hash=nil, passed_options={}) @sub_elements = {} end + def marshal_load(attributes) + hash, @options = attributes + @deep_dup = DeepDup.new(@options) + @sub_elements = {} + super(hash) + end + + def marshal_dump + [super, @options] + end if OpenStruct.public_instance_methods.include?(:initialize_copy) def initialize_copy(orig) diff --git a/spec/recursive_open_struct/recursion_spec.rb b/spec/recursive_open_struct/recursion_spec.rb index 3fb99c7..4b094d5 100644 --- a/spec/recursive_open_struct/recursion_spec.rb +++ b/spec/recursive_open_struct/recursion_spec.rb @@ -37,6 +37,14 @@ expect(ros.blah.changed).to eql 'backing' end + it "handles being dump then loaded by Marshal" do + foo_struct = [RecursiveOpenStruct.new] + bar_struct = RecursiveOpenStruct.new(foo: foo_struct) + serialized = Marshal.dump(bar_struct) + + expect(Marshal.load(serialized).foo).to eq(foo_struct) + end + describe "handling loops in the original Hashes" do let(:h1) { { :a => 'a'} } let(:h2) { { :a => 'b', :h1 => h1 } } @@ -182,6 +190,17 @@ let(:blah_list) { [ { :foo => '1' }, { :foo => '2' }, 'baz' ] } let(:h) { { :blah => blah_list } } + context "when dump and loaded by Marshal" do + let(:test) { RecursiveOpenStruct.new(h, :recurse_over_arrays => true) } + subject { Marshal.load(Marshal.dump(test))} + + it { expect(subject.blah.length).to eq 3 } + it { expect(subject.blah[0].foo).to eq '1' } + it { expect(subject.blah[1].foo).to eq '2' } + it { expect(subject.blah_as_a_hash).to eq blah_list } + it { expect(subject.blah[2]).to eq 'baz' } + end + context "when recursing over arrays is enabled" do subject { RecursiveOpenStruct.new(h, :recurse_over_arrays => true) }