recursive-open-struct-sd 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.gitignore +50 -0
- data/.rspec +1 -0
- data/.travis.yml +13 -0
- data/AUTHORS.txt +15 -0
- data/CHANGELOG.md +151 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +21 -0
- data/README.md +60 -0
- data/Rakefile +60 -0
- data/lib/recursive-open-struct.rb +1 -0
- data/lib/recursive_open_struct.rb +130 -0
- data/lib/recursive_open_struct/debug_inspect.rb +38 -0
- data/lib/recursive_open_struct/deep_dup.rb +32 -0
- data/lib/recursive_open_struct/ruby_19_backport.rb +27 -0
- data/lib/recursive_open_struct/version.rb +7 -0
- data/recursive-open-struct-sd.gemspec +46 -0
- data/spec/recursive_open_struct/debug_inspect_spec.rb +70 -0
- data/spec/recursive_open_struct/indifferent_access_spec.rb +166 -0
- data/spec/recursive_open_struct/open_struct_behavior_spec.rb +92 -0
- data/spec/recursive_open_struct/ostruct_2_0_0_spec.rb +105 -0
- data/spec/recursive_open_struct/recursion_and_subclassing_spec.rb +14 -0
- data/spec/recursive_open_struct/recursion_spec.rb +299 -0
- data/spec/spec_helper.rb +19 -0
- metadata +174 -0
@@ -0,0 +1,105 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require 'recursive_open_struct'
|
3
|
+
|
4
|
+
describe RecursiveOpenStruct do
|
5
|
+
|
6
|
+
let(:hash) { {:foo => 'foo', 'bar' => :bar} }
|
7
|
+
subject(:ros) { RecursiveOpenStruct.new(hash) }
|
8
|
+
|
9
|
+
describe "OpenStruct 2.0 methods" do
|
10
|
+
|
11
|
+
context "Hash style setter" do
|
12
|
+
|
13
|
+
it "method exists" do
|
14
|
+
expect(ros.respond_to?('[]=')).to be_truthy
|
15
|
+
end
|
16
|
+
|
17
|
+
it "changes the value" do
|
18
|
+
ros[:foo] = :foo
|
19
|
+
ros.foo = :foo
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
context "delete_field" do
|
25
|
+
|
26
|
+
before(:each) { ros.delete_field :foo }
|
27
|
+
|
28
|
+
it "removes the value" do
|
29
|
+
expect(ros.foo).to be_nil
|
30
|
+
expect(ros.to_h).to_not include(:foo)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "removes the getter method" do
|
34
|
+
is_expected.to_not respond_to :foo
|
35
|
+
end
|
36
|
+
|
37
|
+
it "removes the setter method" do
|
38
|
+
expect(ros.respond_to? 'foo=').to be_falsey
|
39
|
+
end
|
40
|
+
|
41
|
+
it "works with indifferent access" do
|
42
|
+
expect(ros.delete_field :bar).to eq :bar
|
43
|
+
is_expected.to_not respond_to :bar
|
44
|
+
is_expected.to_not respond_to 'bar='
|
45
|
+
expect(ros.to_h).to be_empty
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
context "eql?" do
|
51
|
+
subject(:new_ros) { ros.dup }
|
52
|
+
|
53
|
+
context "with identical ROS" do
|
54
|
+
subject { ros }
|
55
|
+
it { is_expected.to be_eql ros }
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with similar ROS" do
|
59
|
+
subject { RecursiveOpenStruct.new(hash) }
|
60
|
+
it { is_expected.to be_eql ros }
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with same Hash" do
|
64
|
+
subject { RecursiveOpenStruct.new(hash, recurse_over_arrays: true) }
|
65
|
+
it { is_expected.to be_eql ros }
|
66
|
+
end
|
67
|
+
|
68
|
+
context "with duplicated ROS" do
|
69
|
+
subject { ros.dup }
|
70
|
+
|
71
|
+
it "fails on different value" do
|
72
|
+
subject.foo = 'bar'
|
73
|
+
is_expected.not_to be_eql ros
|
74
|
+
end
|
75
|
+
|
76
|
+
it "fails on missing field" do
|
77
|
+
subject.delete_field :bar
|
78
|
+
is_expected.not_to be_eql ros
|
79
|
+
end
|
80
|
+
|
81
|
+
it "fails on added field" do
|
82
|
+
subject.baz = :baz
|
83
|
+
is_expected.not_to be_eql ros
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
context "hash" do
|
91
|
+
it "calculates table hash" do
|
92
|
+
expect(ros.hash).to be ros.instance_variable_get('@table').hash
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
context "each_pair" do
|
98
|
+
it "iterates over hash keys, with keys as symbol" do
|
99
|
+
expect(ros.each_pair).to match ({:foo => 'foo', :bar => :bar}.each_pair)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require 'recursive_open_struct'
|
3
|
+
|
4
|
+
describe RecursiveOpenStruct do
|
5
|
+
describe "subclassing RecursiveOpenStruct" do
|
6
|
+
let(:subclass) { Class.new(RecursiveOpenStruct) }
|
7
|
+
|
8
|
+
subject(:rossc) { subclass.new({ :one => [{:two => :three}] }, recurse_over_arrays: true) }
|
9
|
+
|
10
|
+
specify "nested objects use the subclass of the parent" do
|
11
|
+
expect(rossc.one.first.class).to eq subclass
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,299 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
require 'recursive_open_struct'
|
3
|
+
|
4
|
+
describe RecursiveOpenStruct do
|
5
|
+
|
6
|
+
describe "recursive behavior" do
|
7
|
+
let(:h) { { :blah => { :another => 'value' } } }
|
8
|
+
subject(:ros) { RecursiveOpenStruct.new(h) }
|
9
|
+
|
10
|
+
it "can convert the entire hash tree back into a hash" do
|
11
|
+
blank_obj = Object.new
|
12
|
+
h = {:asdf => 'John Smith', :foo => [{:bar => blank_obj}, {:baz => nil}]}
|
13
|
+
ros = RecursiveOpenStruct.new(h)
|
14
|
+
|
15
|
+
expect(ros.to_h).to eq h
|
16
|
+
expect(ros.to_hash).to eq h
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns accessed hashes as RecursiveOpenStructs instead of hashes" do
|
20
|
+
expect(subject.blah.another).to eq 'value'
|
21
|
+
end
|
22
|
+
|
23
|
+
it "handles subscript notation the same way as dotted notation" do
|
24
|
+
expect(subject.blah.another).to eq subject[:blah].another
|
25
|
+
end
|
26
|
+
|
27
|
+
it "uses #key_as_a_hash to return key as a Hash" do
|
28
|
+
expect(subject.blah_as_a_hash).to eq({ :another => 'value' })
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "handling loops in the original Hashes" do
|
32
|
+
let(:h1) { { :a => 'a'} }
|
33
|
+
let(:h2) { { :a => 'b', :h1 => h1 } }
|
34
|
+
before(:each) { h1[:h2] = h2 }
|
35
|
+
|
36
|
+
subject { RecursiveOpenStruct.new(h2) }
|
37
|
+
|
38
|
+
it { expect(subject.h1.a).to eq 'a' }
|
39
|
+
it { expect(subject.h1.h2.a).to eq 'b' }
|
40
|
+
it { expect(subject.h1.h2.h1.a).to eq 'a' }
|
41
|
+
it { expect(subject.h1.h2.h1.h2.a).to eq 'b' }
|
42
|
+
it { expect(subject.h1).to eq subject.h1.h2.h1 }
|
43
|
+
it { expect(subject.h1).to_not eq subject.h1.h2 }
|
44
|
+
end # describe handling loops in the origin Hashes
|
45
|
+
|
46
|
+
it "can modify a key of a sub-element" do
|
47
|
+
h = {
|
48
|
+
:blah => {
|
49
|
+
:blargh => 'Brad'
|
50
|
+
}
|
51
|
+
}
|
52
|
+
ros = RecursiveOpenStruct.new(h)
|
53
|
+
ros.blah.blargh = "Janet"
|
54
|
+
|
55
|
+
expect(ros.blah.blargh).to eq "Janet"
|
56
|
+
end
|
57
|
+
|
58
|
+
context "after a sub-element has been modified" do
|
59
|
+
let(:hash) do
|
60
|
+
{ :blah => { :blargh => "Brad" }, :some_array => [ 1, 2, 3] }
|
61
|
+
end
|
62
|
+
let(:updated_hash) do
|
63
|
+
{ :blah => { :blargh => "Janet" }, :some_array => [ 1, 2, 3] }
|
64
|
+
end
|
65
|
+
|
66
|
+
subject { RecursiveOpenStruct.new(hash) }
|
67
|
+
|
68
|
+
before(:each) { subject.blah.blargh = "Janet" }
|
69
|
+
|
70
|
+
describe ".to_h" do
|
71
|
+
it "returns a hash tree that contains those modifications" do
|
72
|
+
expect(subject.to_h).to eq updated_hash
|
73
|
+
end
|
74
|
+
|
75
|
+
specify "modifying the returned hash tree does not modify the ROS" do
|
76
|
+
subject.to_h[:blah][:blargh] = "Dr Scott"
|
77
|
+
|
78
|
+
expect(subject.blah.blargh).to eq "Janet"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it "does not mutate the original hash tree passed to the constructor" do
|
83
|
+
expect(hash[:blah][:blargh]).to eq 'Brad'
|
84
|
+
end
|
85
|
+
|
86
|
+
it "limits the deep-copy to the initial hash tree" do
|
87
|
+
subject.some_array[0] = 4
|
88
|
+
|
89
|
+
expect(hash[:some_array][0]).to eq 4
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#dup" do
|
93
|
+
let(:duped_subject) { subject.dup }
|
94
|
+
|
95
|
+
it "preserves sub-element modifications" do
|
96
|
+
expect(duped_subject.blah.blargh).to eq subject.blah.blargh
|
97
|
+
end
|
98
|
+
|
99
|
+
it "allows the copy's sub-elements to be modified independently from the original's" do
|
100
|
+
expect(subject.blah.blargh).to eq "Janet"
|
101
|
+
|
102
|
+
duped_subject.blah.blargh = "Dr. Scott"
|
103
|
+
|
104
|
+
expect(subject.blah.blargh).to eq "Janet"
|
105
|
+
expect(duped_subject.blah.blargh).to eq "Dr. Scott"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when memoizing and then modifying entire recursive structures" do
|
111
|
+
subject do
|
112
|
+
RecursiveOpenStruct.new(
|
113
|
+
{ :blah => original_blah }, :recurse_over_arrays => true)
|
114
|
+
end
|
115
|
+
|
116
|
+
before(:each) { subject.blah } # enforce memoization
|
117
|
+
|
118
|
+
context "when modifying an entire Hash" do
|
119
|
+
let(:original_blah) { { :a => 'A', :b => 'B' } }
|
120
|
+
let(:new_blah) { { :something_new => "C" } }
|
121
|
+
|
122
|
+
before(:each) { subject.blah = new_blah }
|
123
|
+
|
124
|
+
it "returns the modified value instead of the memoized one" do
|
125
|
+
expect(subject.blah.something_new).to eq "C"
|
126
|
+
end
|
127
|
+
|
128
|
+
specify "the old value no longer exists" do
|
129
|
+
expect(subject.blah.a).to be_nil
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when modifying an entire Array" do
|
134
|
+
let(:original_blah) { [1, 2, 3] }
|
135
|
+
|
136
|
+
it "returns the modified value instead of the memoized one" do
|
137
|
+
new_blah = [4, 5, 6]
|
138
|
+
subject.blah = new_blah
|
139
|
+
expect(subject.blah).to eq new_blah
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe 'recursing over arrays' do
|
145
|
+
let(:blah_list) { [ { :foo => '1' }, { :foo => '2' }, 'baz' ] }
|
146
|
+
let(:h) { { :blah => blah_list } }
|
147
|
+
|
148
|
+
context "when recursing over arrays is enabled" do
|
149
|
+
subject { RecursiveOpenStruct.new(h, :recurse_over_arrays => true) }
|
150
|
+
|
151
|
+
it { expect(subject.blah.length).to eq 3 }
|
152
|
+
it { expect(subject.blah[0].foo).to eq '1' }
|
153
|
+
it { expect(subject.blah[1].foo).to eq '2' }
|
154
|
+
it { expect(subject.blah_as_a_hash).to eq blah_list }
|
155
|
+
it { expect(subject.blah[2]).to eq 'baz' }
|
156
|
+
|
157
|
+
context "when an inner value changes" do
|
158
|
+
let(:updated_blah_list) { [ { :foo => '1' }, { :foo => 'Dr Scott' }, 'baz' ] }
|
159
|
+
let(:updated_h) { { :blah => updated_blah_list } }
|
160
|
+
|
161
|
+
before(:each) { subject.blah[1].foo = "Dr Scott" }
|
162
|
+
|
163
|
+
it "Retains changes across Array lookups" do
|
164
|
+
expect(subject.blah[1].foo).to eq "Dr Scott"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "propagates the changes through to .to_h across Array lookups" do
|
168
|
+
expect(subject.to_h).to eq({
|
169
|
+
:blah => [ { :foo => '1' }, { :foo => "Dr Scott" }, 'baz' ]
|
170
|
+
})
|
171
|
+
end
|
172
|
+
|
173
|
+
it "deep-copies hashes within Arrays" do
|
174
|
+
subject.to_h[:blah][1][:foo] = "Rocky"
|
175
|
+
|
176
|
+
expect(subject.blah[1].foo).to eq "Dr Scott"
|
177
|
+
end
|
178
|
+
|
179
|
+
it "does not mutate the input hash passed to the constructor" do
|
180
|
+
expect(h[:blah][1][:foo]).to eq '2'
|
181
|
+
end
|
182
|
+
|
183
|
+
it "the deep copy recurses over Arrays as well" do
|
184
|
+
expect(h[:blah][1][:foo]).to eq '2'
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "#dup" do
|
188
|
+
let(:duped_subject) { subject.dup }
|
189
|
+
|
190
|
+
it "preserves sub-element modifications" do
|
191
|
+
expect(duped_subject.blah[1].foo).to eq subject.blah[1].foo
|
192
|
+
end
|
193
|
+
|
194
|
+
it "allows the copy's sub-elements to be modified independently from the original's" do
|
195
|
+
duped_subject.blah[1].foo = "Rocky"
|
196
|
+
|
197
|
+
expect(duped_subject.blah[1].foo).to eq "Rocky"
|
198
|
+
expect(subject.blah[1].foo).to eq "Dr Scott"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context "when array is nested deeper" do
|
204
|
+
let(:deep_hash) { { :foo => { :blah => blah_list } } }
|
205
|
+
subject { RecursiveOpenStruct.new(deep_hash, :recurse_over_arrays => true) }
|
206
|
+
|
207
|
+
it { expect(subject.foo.blah.length).to eq 3 }
|
208
|
+
it "Retains changes across Array lookups" do
|
209
|
+
subject.foo.blah[1].foo = "Dr Scott"
|
210
|
+
expect(subject.foo.blah[1].foo).to eq "Dr Scott"
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
context "when array is in an array" do
|
216
|
+
let(:haah) { { :blah => [ blah_list ] } }
|
217
|
+
subject { RecursiveOpenStruct.new(haah, :recurse_over_arrays => true) }
|
218
|
+
|
219
|
+
it { expect(subject.blah.length).to eq 1 }
|
220
|
+
it { expect(subject.blah[0].length).to eq 3 }
|
221
|
+
it "Retains changes across Array lookups" do
|
222
|
+
subject.blah[0][1].foo = "Dr Scott"
|
223
|
+
|
224
|
+
expect(subject.blah[0][1].foo).to eq "Dr Scott"
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
|
229
|
+
end # when recursing over arrays is enabled
|
230
|
+
|
231
|
+
context "when recursing over arrays is disabled" do
|
232
|
+
subject { RecursiveOpenStruct.new(h) }
|
233
|
+
|
234
|
+
it { expect(subject.blah.length).to eq 3 }
|
235
|
+
it { expect(subject.blah[0]).to eq({ :foo => '1' }) }
|
236
|
+
it { expect(subject.blah[0][:foo]).to eq '1' }
|
237
|
+
end # when recursing over arrays is disabled
|
238
|
+
|
239
|
+
describe 'modifying an array and recursing over it' do
|
240
|
+
let(:h) { {} }
|
241
|
+
subject { RecursiveOpenStruct.new(h, recurse_over_arrays: true) }
|
242
|
+
|
243
|
+
context 'when adding an array with hashes into the tree' do
|
244
|
+
before(:each) do
|
245
|
+
subject.mystery = {}
|
246
|
+
subject.mystery.science = [{ theatre: 9000 }]
|
247
|
+
end
|
248
|
+
|
249
|
+
it "ROS's it" do
|
250
|
+
expect(subject.mystery.science[0].theatre).to eq 9000
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context 'when appending a hash to an array' do
|
255
|
+
before(:each) do
|
256
|
+
subject.mystery = {}
|
257
|
+
subject.mystery.science = []
|
258
|
+
subject.mystery.science << { theatre: 9000 }
|
259
|
+
end
|
260
|
+
|
261
|
+
it "ROS's it" do
|
262
|
+
expect(subject.mystery.science[0].theatre).to eq 9000
|
263
|
+
end
|
264
|
+
|
265
|
+
specify "the changes show up in .to_h" do
|
266
|
+
expect(subject.to_h).to eq({ mystery: { science: [{theatre: 9000}]}})
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
context 'after appending a hash to an array' do
|
271
|
+
before(:each) do
|
272
|
+
subject.mystery = {}
|
273
|
+
subject.mystery.science = []
|
274
|
+
subject.mystery.science[0] = {}
|
275
|
+
end
|
276
|
+
|
277
|
+
it "can have new values be set" do
|
278
|
+
expect do
|
279
|
+
subject.mystery.science[0].theatre = 9000
|
280
|
+
end.to_not raise_error
|
281
|
+
|
282
|
+
expect(subject.mystery.science[0].theatre).to eq 9000
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end # modifying an array and then recursing
|
286
|
+
end # recursing over arrays
|
287
|
+
|
288
|
+
describe 'nested nil values' do
|
289
|
+
let(:h) { { foo: { bar: nil }} }
|
290
|
+
it 'returns nil' do
|
291
|
+
expect(subject.foo.bar).to be_nil
|
292
|
+
end
|
293
|
+
|
294
|
+
it 'returns a hash with the key and a nil value' do
|
295
|
+
expect(subject.to_hash).to eq({ foo: { bar: nil }})
|
296
|
+
end
|
297
|
+
end # nested nil values
|
298
|
+
end # recursive behavior
|
299
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
if ENV['COVERAGE'] == 'true'
|
7
|
+
require 'simplecov'
|
8
|
+
SimpleCov.start
|
9
|
+
end
|
10
|
+
|
11
|
+
# Requires supporting files with custom matchers and macros, etc,
|
12
|
+
# in ./support/ and its subdirectories.
|
13
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.run_all_when_everything_filtered = true
|
17
|
+
config.filter_run :focus
|
18
|
+
# config.expect_with(:rspec) { |c| c.syntax = :should }
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: recursive-open-struct-sd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- William (B.J.) Snow Orvis
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: simplecov
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: |
|
98
|
+
RecursiveOpenStruct is a subclass of OpenStruct. It differs from
|
99
|
+
OpenStruct in that it allows nested hashes to be treated in a recursive
|
100
|
+
fashion. For example:
|
101
|
+
|
102
|
+
ros = RecursiveOpenStruct.new({ :a => { :b => 'c' } })
|
103
|
+
ros.a.b # 'c'
|
104
|
+
|
105
|
+
Also, nested hashes can still be accessed as hashes:
|
106
|
+
|
107
|
+
ros.a_as_a_hash # { :b => 'c' }
|
108
|
+
|
109
|
+
> This is a fork of the original recursive-open-struct
|
110
|
+
> to include a fix for https://github.com/aetherknight/recursive-open-struct/issues/46
|
111
|
+
email: aetherknight@gmail.com
|
112
|
+
executables: []
|
113
|
+
extensions: []
|
114
|
+
extra_rdoc_files:
|
115
|
+
- CHANGELOG.md
|
116
|
+
- LICENSE.txt
|
117
|
+
- README.md
|
118
|
+
files:
|
119
|
+
- ".document"
|
120
|
+
- ".gitignore"
|
121
|
+
- ".rspec"
|
122
|
+
- ".travis.yml"
|
123
|
+
- AUTHORS.txt
|
124
|
+
- CHANGELOG.md
|
125
|
+
- Gemfile
|
126
|
+
- LICENSE.txt
|
127
|
+
- README.md
|
128
|
+
- Rakefile
|
129
|
+
- lib/recursive-open-struct.rb
|
130
|
+
- lib/recursive_open_struct.rb
|
131
|
+
- lib/recursive_open_struct/debug_inspect.rb
|
132
|
+
- lib/recursive_open_struct/deep_dup.rb
|
133
|
+
- lib/recursive_open_struct/ruby_19_backport.rb
|
134
|
+
- lib/recursive_open_struct/version.rb
|
135
|
+
- recursive-open-struct-sd.gemspec
|
136
|
+
- spec/recursive_open_struct/debug_inspect_spec.rb
|
137
|
+
- spec/recursive_open_struct/indifferent_access_spec.rb
|
138
|
+
- spec/recursive_open_struct/open_struct_behavior_spec.rb
|
139
|
+
- spec/recursive_open_struct/ostruct_2_0_0_spec.rb
|
140
|
+
- spec/recursive_open_struct/recursion_and_subclassing_spec.rb
|
141
|
+
- spec/recursive_open_struct/recursion_spec.rb
|
142
|
+
- spec/spec_helper.rb
|
143
|
+
homepage: http://github.com/aetherknight/recursive-open-struct
|
144
|
+
licenses:
|
145
|
+
- MIT
|
146
|
+
metadata: {}
|
147
|
+
post_install_message:
|
148
|
+
rdoc_options: []
|
149
|
+
require_paths:
|
150
|
+
- lib
|
151
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
version: '0'
|
156
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
requirements: []
|
162
|
+
rubyforge_project:
|
163
|
+
rubygems_version: 2.5.1
|
164
|
+
signing_key:
|
165
|
+
specification_version: 4
|
166
|
+
summary: OpenStruct subclass that returns nested hash attributes as RecursiveOpenStructs
|
167
|
+
test_files:
|
168
|
+
- spec/recursive_open_struct/debug_inspect_spec.rb
|
169
|
+
- spec/recursive_open_struct/indifferent_access_spec.rb
|
170
|
+
- spec/recursive_open_struct/open_struct_behavior_spec.rb
|
171
|
+
- spec/recursive_open_struct/ostruct_2_0_0_spec.rb
|
172
|
+
- spec/recursive_open_struct/recursion_and_subclassing_spec.rb
|
173
|
+
- spec/recursive_open_struct/recursion_spec.rb
|
174
|
+
- spec/spec_helper.rb
|