right_support 2.8.37 → 2.8.38
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 +4 -4
- data/VERSION +1 -1
- data/lib/right_support/data/hash_tools.rb +70 -3
- data/right_support.gemspec +4 -4
- data/spec/data/hash_tools_spec.rb +67 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0cb72f5d96896f6a249867296e5a6ee14021caa
|
4
|
+
data.tar.gz: 930f29d6b579d374ddadf6636c3687aeb12f394e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bc745e71199150c1c3097efe6ba4ec77549e6c5d34ae7fdd899710f5122adde38e77b01a56f4e826e8e49a297eed2534fc1be78cf72ffb924e79beb6335b064
|
7
|
+
data.tar.gz: e823929462c375b3bb12f51c91fd39780de10eec2194232d32c5ea649166709f523bc2cad31f4030d588a9f95eebd38ba84d969c6f4aa9a195f223d188fbac28
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.8.
|
1
|
+
2.8.38
|
@@ -138,6 +138,13 @@ module RightSupport::Data
|
|
138
138
|
# === Return
|
139
139
|
# @return [Hash] deep cloned hash
|
140
140
|
def self.deep_clone(original, &leaf_callback)
|
141
|
+
# note that .clone preserves .frozen? state so this legacy method will
|
142
|
+
# attempt to modify a still-frozen hash/array and raise an exception.
|
143
|
+
# see deep_clone2 which clones by creating a new instance of the object
|
144
|
+
# class and produce an unfrozen clone of the hash/array.
|
145
|
+
# as a side note, calling .dup does not preserve .frozen? state but is has
|
146
|
+
# its own side effects, which is why we have more specific logic like
|
147
|
+
# leaf_callback and .duplicable?
|
141
148
|
result = original.clone
|
142
149
|
result.each do |k, v|
|
143
150
|
if hashable?(v)
|
@@ -196,8 +203,36 @@ module RightSupport::Data
|
|
196
203
|
end
|
197
204
|
end
|
198
205
|
|
199
|
-
# Deeply
|
200
|
-
#
|
206
|
+
# Deeply freezes the given hash/array and all of their non-hierarchical
|
207
|
+
# elements in a hierarchichal data structure such that an attempt to modify
|
208
|
+
# any part of it will raise an exception.
|
209
|
+
#
|
210
|
+
# === Parameters
|
211
|
+
# @param [Object] any kind of object
|
212
|
+
#
|
213
|
+
# === Return
|
214
|
+
# @return [Object] deeply frozen object
|
215
|
+
def self.deep_freeze!(any)
|
216
|
+
if hashable?(any)
|
217
|
+
# clone to a new instance of hashable class with deep cloning.
|
218
|
+
any.each do |k, v|
|
219
|
+
# notes:
|
220
|
+
# a) either key or value of a hash could be a complex type.
|
221
|
+
# b) Hash freezes simple type keys upon insertion out of necessity to
|
222
|
+
# avoid spontaneous rehashing. Hash will not freeze complex types
|
223
|
+
# used as keys so we will (re)freeze all keys for safety.
|
224
|
+
deep_freeze!(k)
|
225
|
+
deep_freeze!(v)
|
226
|
+
end
|
227
|
+
elsif any.kind_of?(::Array)
|
228
|
+
# traverse arrays
|
229
|
+
any.each { |e| deep_freeze!(e) }
|
230
|
+
end
|
231
|
+
any.freeze
|
232
|
+
end
|
233
|
+
|
234
|
+
# Deeply mashes and duplicates (clones) a hashable using deep_clone2 and our
|
235
|
+
# own version of Mash.
|
201
236
|
#
|
202
237
|
# The advantage of Mash over Hash is, of course, to be able to use either
|
203
238
|
# a String or Symbol as a key for the same value.
|
@@ -221,7 +256,39 @@ module RightSupport::Data
|
|
221
256
|
deep_clone2(any, options, &leaf_callback)
|
222
257
|
end
|
223
258
|
|
224
|
-
# Performs a deep
|
259
|
+
# Performs a deep clone and merge of one hash into another, similar in
|
260
|
+
# behavior to Hash#merge
|
261
|
+
#
|
262
|
+
# === Parameters
|
263
|
+
# @param [Hash] target hash containing original data to be replaced in the
|
264
|
+
# resulting hash
|
265
|
+
# @param [Hash] source hash containing data to recursively assign or nil or
|
266
|
+
# empty
|
267
|
+
#
|
268
|
+
# === Return
|
269
|
+
# @return [Hash] to_hash result of merge
|
270
|
+
def self.deep_merge(target, source)
|
271
|
+
# merge or replace any values that appear in source.
|
272
|
+
result = target.class.new
|
273
|
+
(source || {}).each do |k, v|
|
274
|
+
if hashable?(target[k]) && hashable?(v)
|
275
|
+
result[k] = deep_merge(target[k], v)
|
276
|
+
else
|
277
|
+
result[k] = v
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# deep clone any target-only value.
|
282
|
+
target.each do |k, v|
|
283
|
+
unless result.has_key?(k)
|
284
|
+
result[k] = deep_clone2(v)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
result
|
288
|
+
end
|
289
|
+
|
290
|
+
# Performs a deep merge (but not a deep clone) of one hash into another,
|
291
|
+
# similar in behavior to Hash#merge!
|
225
292
|
#
|
226
293
|
# === Parameters
|
227
294
|
# @param [Hash] target hash to contain original and merged data
|
data/right_support.gemspec
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: right_support 2.8.
|
5
|
+
# stub: right_support 2.8.38 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "right_support"
|
9
|
-
s.version = "2.8.
|
9
|
+
s.version = "2.8.38"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Tony Spataro", "Sergey Sergyenko", "Ryan Williamson", "Lee Kirchhoff", "Alexey Karpik", "Scott Messier"]
|
14
|
-
s.date = "2014-
|
14
|
+
s.date = "2014-12-05"
|
15
15
|
s.description = "A toolkit of useful, reusable foundation code created by RightScale."
|
16
16
|
s.email = "support@rightscale.com"
|
17
17
|
s.extra_rdoc_files = [
|
@@ -148,7 +148,7 @@ Gem::Specification.new do |s|
|
|
148
148
|
]
|
149
149
|
s.homepage = "https://github.com/rightscale/right_support"
|
150
150
|
s.licenses = ["MIT"]
|
151
|
-
s.rubygems_version = "2.2.
|
151
|
+
s.rubygems_version = "2.2.2"
|
152
152
|
s.summary = "Reusable foundation code."
|
153
153
|
|
154
154
|
if s.respond_to? :specification_version then
|
@@ -257,6 +257,72 @@ describe RightSupport::Data::HashTools do
|
|
257
257
|
end
|
258
258
|
end
|
259
259
|
|
260
|
+
context '#deep_freeze!' do
|
261
|
+
it "should deep freeze hashes and arrays" do
|
262
|
+
original = {
|
263
|
+
'a' => ' s ',
|
264
|
+
'b' => {
|
265
|
+
'h' => ' s2 ',
|
266
|
+
'a' => [ 1, { :nested => ' s3 ' } ]
|
267
|
+
}
|
268
|
+
}
|
269
|
+
original.each do |k, v|
|
270
|
+
# note that Hash freezes keys upon insertion out of necessity to avoid
|
271
|
+
# spontaneous rehashing.
|
272
|
+
k.should be_frozen
|
273
|
+
v.should_not be_frozen
|
274
|
+
end
|
275
|
+
original['b']['a'][1][:nested].should_not be_frozen
|
276
|
+
subject.deep_freeze!(original)
|
277
|
+
original.each do |k, v|
|
278
|
+
k.should be_frozen
|
279
|
+
v.should be_frozen
|
280
|
+
end
|
281
|
+
original['b']['a'][1][:nested].should be_frozen
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
context '#deep_merge' do
|
286
|
+
{
|
287
|
+
:identical => {
|
288
|
+
:left => { :one => 1 },
|
289
|
+
:right => { :one => 1 },
|
290
|
+
:expected => { :one => 1 } },
|
291
|
+
:disjoint => {
|
292
|
+
:left => { :one => 1 },
|
293
|
+
:right => { :two => 1 },
|
294
|
+
:expected => { :one => 1, :two => 1 } },
|
295
|
+
:value_diff => {
|
296
|
+
:left => { :one => 1 },
|
297
|
+
:right => { :one => 2 },
|
298
|
+
:expected => { :one => 2 } },
|
299
|
+
:recursive_disjoint => {
|
300
|
+
:left => { :one => { :a => 1, :b => 2 }, :two => 3 },
|
301
|
+
:right => { :one => { :a => 1 }, :two => 3 },
|
302
|
+
:expected => { :one => { :a => 1, :b => 2 }, :two => 3 } },
|
303
|
+
:recursive_value_diff => {
|
304
|
+
:left => { :one => { :a => 1, :b => 2 }, :two => 3 },
|
305
|
+
:right => { :one => { :a => 1, :b => 3 }, :two => 3 },
|
306
|
+
:expected => { :one => { :a => 1, :b => 3 }, :two => 3 } },
|
307
|
+
:recursive_disjoint_and_value_diff => {
|
308
|
+
:left => { :one => { :a => 1, :b => 2, :c => 3 }, :two => 3, :three => 4 },
|
309
|
+
:right => { :one => { :a => 1, :b => 3, :d => 4 }, :two => 5, :four => 6 },
|
310
|
+
:expected => { :one => { :a => 1, :b => 3, :c => 3 , :d => 4 }, :two => 5, :three => 4, :four => 6 } }
|
311
|
+
}.each do |kind, data|
|
312
|
+
it "should deep merge #{kind} hashes" do
|
313
|
+
left_same_as_expected = data[:left] == data[:expected]
|
314
|
+
actual = subject.deep_merge(data[:left], data[:right])
|
315
|
+
actual.should == data[:expected]
|
316
|
+
|
317
|
+
# original should be unmodified.
|
318
|
+
actual.object_id.should_not == data[:left].object_id
|
319
|
+
unless left_same_as_expected
|
320
|
+
data[:left].should_not == data[:expected]
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
260
326
|
context '#deep_merge!' do
|
261
327
|
{
|
262
328
|
:identical => {
|
@@ -287,6 +353,7 @@ describe RightSupport::Data::HashTools do
|
|
287
353
|
it "should deep merge #{kind} hashes" do
|
288
354
|
actual = subject.deep_merge!(data[:left], data[:right])
|
289
355
|
actual.should == data[:expected]
|
356
|
+
actual.object_id.should == data[:left].object_id # original returned modified
|
290
357
|
end
|
291
358
|
end
|
292
359
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: right_support
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.8.
|
4
|
+
version: 2.8.38
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Spataro
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2014-
|
16
|
+
date: 2014-12-05 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: rake
|
@@ -239,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
239
239
|
version: '0'
|
240
240
|
requirements: []
|
241
241
|
rubyforge_project:
|
242
|
-
rubygems_version: 2.2.
|
242
|
+
rubygems_version: 2.2.2
|
243
243
|
signing_key:
|
244
244
|
specification_version: 4
|
245
245
|
summary: Reusable foundation code.
|