Я пытаюсь создать гем обертки API, и возникают проблемы с преобразованием ключей хеш-функции в более Rubyish формат из JSON, который возвращает API.
JSON содержит несколько слоев вложенности, как хеши, так и массивы. Я хочу рекурсивно конвертировать все ключи в snake_case для более легкого использования.
Вот что у меня так далеко:
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
Выше приведен вызов этого метода для преобразования строк в 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
В идеале результат должен быть похож на следующее:
hash = {:HashKey => {:NestedHashKey => [{:Key => "value"}]}}
convert_hash_keys(hash)
# => {:hash_key => {:nested_hash_key => [{:key => "value"}]}}
Я получаю неправильную рекурсию, и каждая версия такого рода решений, которую я пробовал, либо не преобразует символы за пределы первого уровня, либо выходит за борт и пытается преобразовать весь хэш, включая значения.
Попытка решить все это во вспомогательном классе, вместо того, чтобы по возможности модифицировать реальные функции Hash и String.
Заранее спасибо.