I have multiple YAML (localization) files. I parse them and convert to hash in Ruby.
For example this is one of them:
hello: Hallo
messages:
alerts:
yay: Da!
no: Nein
deep:
nested:
another:
level:
hi: Hi!
test: Test!
Basically, this is look like a locale file in Rails App using YAML.
What I want to do is iterate this Hash recursively and get key and value. So that i can translate values one-by-one from API Endpoint like Google Translate. I want to keep nested hashes in same schema so that Rails can find by keys.
I know i can use nested loops but there is no guarantee that nested hashes is a known number of. How can I iterate this hash recursively so i can manipulate values (translate/replace)?
Expected Result: (after used translation service from API call)
hello: Hello
messages:
alerts:
yay: Yup!
no: No
deep:
nested:
another:
level:
hi: Hi!
test: Test!
What I've tried so far:
hash = YAML.load('de.yml') # parse source Deutsch locale
new_hash = {}
hash.each |key, value| do
new_hash[key] = translate_func(value) # here... translate value then assign very same key including parents.
# Do more loops....
end
# Now write this new_hash to yaml file...
But this only manipulate hello
only. To get work with others I have to make a loop. But how many keys are nested is unknown.
How can I iterate over all values of locale hash and keep the schema intact?
And if possible but not mandatory, I would be very happy if we can keep the order of keys on final result. That would be awesome to find missing keys later when manually reviewed.
I am very new to ruby.
I am using Ruby 2.7.2
All answers are correct and I love all of them. However, I would like to be able to control both keys and values. Not just transform by values. Therefore, I accepted an answer that fits to my needs. I was able to do my intention with selected answer.
So, you want to parse recursively until there are no more levels to parse into.
It’s super common in software and referred to as “recursion”. Have a search around to learn more about it - it’ll come up again and again in your journey. Welcome to ruby btw!
As for your actual current problem. Have a read of https://mrxpalmeiras.wordpress.com/2017/03/30/how-to-parse-a-nested-yaml-config-file-in-python-and-ruby/
But also, consider the i18n gem. See this answer https://stackoverflow.com/a/51216931/1777331 and the docs for the gem https://github.com/ruby-i18n/i18n This might fix your problem of handling internationalisation without you having to get into the details of handling yaml files.