def self.deep_mutate(coll, key_or_keys, parent=nil, &block)
keys = key_or_keys.is_a?(Array) ? key_or_keys : [ key_or_keys ]
if coll.is_a?(Hash)
coll.dup.each do |k, v|
unless k.is_a?(String)
coll.delete(k)
k = k.to_s
coll[k] = v
end
if keys.find { |kk| kk.is_a?(Regexp) ? kk.match(k) : kk == k }
if block.arity > 3
block.call(parent, coll, k, v)
else
block.call(coll, k, v)
end
end
if v.is_a?(Array) || v.is_a?(Hash)
deep_mutate(v, keys, coll, &block)
end
end
elsif coll.is_a?(Array)
coll.each { |e| deep_mutate(e, keys, coll, &block) }
end
end