Recursively Symbolize Keys
Given a YAML stream that looks like this:
---
drinks:
martini:
garnish: olive
gibson:
garnish: onion
The Ruby-fied version looks like this:
{"drinks"=>{"gibson"=>{"garnish"=>"onion"}, "martini"=>{"garnish"=>"olive"}}}
But we don’t like string keys, we like symbol keys. A number of libraries exist to extend Hash with interchangeable string- or key-based indexing. But adding a library dependency seems like overkill for symbolizing some keys. Here’s a quick recursive string-to-symbol key converter:
def symbolize_keys(hash)
hash.inject({}){|result, (key, value)|
new_key = case key
when String then key.to_sym
else key
end
new_value = case value
when Hash then symbolize_keys(value)
else value
end
result[new_key] = new_value
result
}
end
Note the block parameters to Hash#inject.
hash.inject({}){|result, (key, value)|
The block arguments would normally be a hash (the accumulator) and a two-element array of [key, value]. Putting parentheses around the second two parameters causes the second argument to be “splatted” into its component parts and assigned to key and value separately.
Let’s take a look at the output.
puts "Symbolized hash:" puts symbolize_keys(YAML.load(yaml)).inspect
Symbolized hash:
{:drinks=>{:martini=>{:garnish=>"olive"}, :gibson=>{:garnish=>"onion"}}}

This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.