| Module | Aquarium::Extensions::HashHelper |
| In: |
lib/aquarium/extensions/hash.rb
|
# File lib/aquarium/extensions/hash.rb, line 7
7: def and other_hash
8: return {} if other_hash.nil? or other_hash.empty?
9: keys2 = Set.new(self.keys).intersection(Set.new(other_hash.keys))
10: result = {}
11: keys2.each do |key|
12: value1 = self[key]
13: value2 = other_hash[key]
14: if block_given?
15: result[key] = yield value1, value2
16: elsif value1 == value2 or value1.eql?(value2)
17: result[key] = value1
18: elsif value1.class == value2.class && value1.respond_to?(:&)
19: result[key] = (value1 & value2)
20: end
21: end
22: result
23: end
It appears that Hash#== uses Object#== (i.e., self.object_id == other.object_id) when comparing hash keys. (Array#== uses the overridden #== for the elements.)
# File lib/aquarium/extensions/hash.rb, line 89
89: def eql_when_keys_compared? other
90: return true if self.object_id == other.object_id
91: return false unless self.class == other.class
92: keys1 = sort_keys(self.keys)
93: keys2 = sort_keys(other.keys)
94: return false unless keys1.eql?(keys2)
95: (0...keys1.size).each do |index|
96: # Handle odd cases where eql? and == behavior differently
97: return false unless self[keys1[index]].eql?(other[keys2[index]]) || self[keys1[index]] == other[keys2[index]]
98: end
99: true
100: end
# File lib/aquarium/extensions/hash.rb, line 102
102: def equivalent_key key
103: i = keys.index(key)
104: i.nil? ? nil : keys[i]
105: end
# File lib/aquarium/extensions/hash.rb, line 59
59: def minus other_hash
60: result = self.dup
61: return result if other_hash.nil? or other_hash.empty?
62: result.each do |key, value|
63: if other_hash.include?(key)
64: value1 = self[key]
65: value2 = other_hash[key]
66: if block_given?
67: result[key] = yield value1, value2
68: elsif value2.nil?
69: # do nothing
70: elsif value1 == value2 or value1.eql?(value2)
71: result.delete key
72: elsif value1.class == value2.class && value1.respond_to?(:-)
73: result[key] = (value1 - value2)
74: else # Hash#merge behavior
75: result.delete key
76: end
77: elsif block_given?
78: # Since the block might change the value's type (e.g., [] => Set...)
79: result[key] = yield result[key], nil
80: end
81: end
82: result
83: end
Union of self with a second hash, which returns a new hash. It‘s different from Hash#merge in that it attempts to merge non-equivalent values for the same key, using a block, if given, or if they are of the same type and respond to #|, using #| to merge the two values. Otherwise, it behaves like Hash#merge.
# File lib/aquarium/extensions/hash.rb, line 32
32: def or other_hash
33: return self if other_hash.nil?
34: result = {}
35: new_keys = self.keys | other_hash.keys
36: new_keys.each do |key|
37: value1 = self[key]
38: value2 = other_hash[key]
39: if block_given?
40: result[key] = yield value1, value2
41: elsif value1.nil? and not value2.nil?
42: result[key] = value2
43: elsif (not value1.nil?) and value2.nil?
44: result[key] = value1
45: elsif value1 == value2 or value1.eql?(value2)
46: result[key] = value1
47: elsif value1.class == value2.class && value1.respond_to?(:|)
48: result[key] = (value1 | value2)
49: else # Hash#merge behavior
50: result[key] = value2
51: end
52: end
53: result
54: end