Module: LazyGraph::HashUtils
- Defined in:
- lib/lazy_graph/hash_utils.rb
Class Method Summary collapse
-
.deep_dup(obj, symbolize: false, signature: nil) ⇒ Object
Deeply duplicates a nested hash or array, preserving object identity.
- .deep_merge(hash, other_hash, path = '') ⇒ Object
- .strip_invalid(obj, parent_list = {}.compare_by_identity) ⇒ Object
Class Method Details
.deep_dup(obj, symbolize: false, signature: nil) ⇒ Object
Deeply duplicates a nested hash or array, preserving object identity. Optionally symbolizes keys on the way, and/or generates a signature.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/lazy_graph/hash_utils.rb', line 9 def deep_dup(obj, symbolize: false, signature: nil) case obj when Hash obj.each_with_object(symbolize ? {}.compare_by_identity : {}) do |(key, value), result| key = \ if !symbolize || key.is_a?(Symbol) key else key.is_a?(String) ? key.to_sym : key.to_s.to_sym end signature[0] ^= key.object_id if signature result[key] = deep_dup(value, symbolize: symbolize, signature: signature) end when Array obj.map { |value| deep_dup(value, symbolize: symbolize, signature: signature) } when String, Numeric, TrueClass, FalseClass, NilClass signature[0] ^= obj.hash if signature obj else obj end end |
.deep_merge(hash, other_hash, path = '') ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/lazy_graph/hash_utils.rb', line 33 def deep_merge(hash, other_hash, path = '') hash.merge(other_hash.transform_keys(&:to_sym)) do |key, this_val, other_val| current_path = path.empty? ? key.to_s : "#{path}.#{key}" if this_val.is_a?(Hash) && other_val.is_a?(Hash) && other_val != this_val deep_merge(this_val, other_val, current_path) elsif this_val.is_a?(Array) && other_val.is_a?(Array) && other_val != this_val (this_val | other_val) else if this_val != other_val && !(this_val.is_a?(Proc) && other_val.is_a?(Proc)) LazyGraph.logger.warn("Conflicting values at #{current_path}: #{this_val.inspect} != #{other_val.inspect}") end other_val end end end |
.strip_invalid(obj, parent_list = {}.compare_by_identity) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/lazy_graph/hash_utils.rb', line 50 def strip_invalid(obj, parent_list = {}.compare_by_identity) return { '^ref': :circular } if (circular_dependency = parent_list[obj]) parent_list[obj] = true case obj when Hash obj.each_with_object({}) do |(key, value), obj| next if value.is_a?(MissingValue) obj[key] = strip_invalid(value, parent_list) end when Struct obj.members.each_with_object({}) do |key, res| next if obj[key].is_a?(MissingValue) next if obj.invisible.include?(key) res[key] = strip_invalid(obj[key], parent_list) end when Array obj.map { |value| strip_invalid(value, parent_list) } when MissingValue nil else obj end ensure parent_list.delete(obj) unless circular_dependency end |