Skip to content

Instantly share code, notes, and snippets.

@alenia
Last active December 21, 2015 07:48
Show Gist options
  • Save alenia/6273654 to your computer and use it in GitHub Desktop.
Save alenia/6273654 to your computer and use it in GitHub Desktop.
Add deep_diff method to Hash to more easily see locations of differences between crazy nested hashes.
class DiffObject
attr :left, :right
def initialize(left, right)
@left = left
@right = right
end
end
class Hash
# a_hash.deep_diff(b_hash) returns:
# key_with_different_value => DiffObject, key_with_hash_value_in_both => {nested_key_with_different_value => DiffObject}
def deep_diff(other_hash)
diff = {}
keys.each do |key|
if (value = self[key]) == (other_value = other_hash[key])
next
elsif (value.is_a?(Hash) && other_value.is_a?(Hash)) || (value.is_a?(Array) && other_value.is_a?(Array))
diff[key] = value.deep_diff(other_value)
else
diff[key] = DiffObject.new(value, other_value)
end
end
(other_hash.keys - keys).each do |key|
diff[key] = DiffObject.new(nil, other_hash[key])
end
diff
end
end
class Array
#not really good about ordering
def deep_diff(other_array)
if self.length != other_array.length
DiffObject.new(self, other_array)
elsif (self.all?{|v| v.is_a?(Hash)} && other_array.all?{|v| v.is_a?(Hash)}) || (self.all?{|v| v.is_a?(Array)} && other_array.all?{|v| v.is_a?(Array)})
self.each_with_index.map{|value,i| value.deep_diff(other_array[i])}
else
DiffObject.new(self, other_array)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment