From 2d2271d457c09554881c91313d4ccc610d85e17c Mon Sep 17 00:00:00 2001 From: Maple Ong Date: Wed, 23 Nov 2022 21:48:53 -0500 Subject: [PATCH] Save info when dumped and loaded by Marshal Previously, ROS did not play well when being dump and loaded with Marshal because the options from ROS did not translate through the serialization. This change saves the information through marshal_dump and then reassigns the information to ROS instance when the object is loaded. --- lib/recursive_open_struct.rb | 8 ++++++++ spec/recursive_open_struct/recursion_spec.rb | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/recursive_open_struct.rb b/lib/recursive_open_struct.rb index 184e5ef..cc27199 100644 --- a/lib/recursive_open_struct.rb +++ b/lib/recursive_open_struct.rb @@ -39,6 +39,14 @@ def initialize(hash=nil, passed_options={}) @sub_elements = {} end + def marshal_load(attributes) + hash, @options, @sub_elements = attributes + super(hash) + end + + def marshal_dump + [super, @options, @sub_elements] + 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) }