Estoy tratando de construir una gema envoltura API, y tener problemas para convertir las claves hash a un formato más Rubyish de la JSON que devuelve la API.Convirtiendo claves hash anidadas de CamelCase a snake_case en Ruby
El JSON contiene múltiples capas de anidamiento, tanto Hashes como Arrays. Lo que quiero hacer es convertir recursivamente todas las claves a snake_case para facilitar su uso.
Esto es lo que tengo hasta ahora:
def convert_hash_keys(value)
return value if (not value.is_a?(Array) and not value.is_a?(Hash))
result = value.inject({}) do |new, (key, value)|
new[to_snake_case(key.to_s).to_sym] = convert_hash_keys(value)
new
end
result
end
Las llamadas por encima de este método para convertir cadenas a snake_case:
def to_snake_case(string)
string.gsub(/::/, '/').
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
gsub(/([a-z\d])([A-Z])/,'\1_\2').
tr("-", "_").
downcase
end
Idealmente, el resultado sería similar a la siguiente:
hash = {:HashKey => {:NestedHashKey => [{:Key => "value"}]}}
convert_hash_keys(hash)
# => {:hash_key => {:nested_hash_key => [{:key => "value"}]}}
Estoy obteniendo la recursión incorrecta, y cada versión de este tipo de solución que he probado tampoco no convierte símbolos más allá del primer nivel, o va por la borda e intenta convertir todo el hash, incluidos los valores.
Tratando de resolver todo esto en una clase de ayuda, en lugar de modificar las funciones reales de Hash y String, si es posible.
Gracias de antemano.
Antes de hacer cualquier otra cosa, 'si (no ... y no ...)' es un lugar perfecto para usar la ley de De Morgan. Deberías escribir 'a menos ... o ...'. – sawa