Ruby JSON parse changes Hash keys

LanguagesNamedAfterCofee picture LanguagesNamedAfterCofee · Sep 25, 2011 · Viewed 46.3k times · Source

Lets say I have this Hash:

{
  :info => [
    {
        :from => "Ryan Bates",
        :message => "sup bra",
        :time => "04:35 AM"
    }
  ]
}

I can call the info array by doing hash[:info].

Now when I turn this into JSON (JSON.generate), and then parse it (JSON.parse), I get this hash:

{
  "info" => [
    {
        "from" => "Ryan Bates",
        "message" => "sup bra",
        "time" => "04:35 AM"
    }
  ]
}

Now if I use hash[:info] it returns nil, but not if I use hash["info"].

Why is this? And is there anyway to fix this incompatibility (besides using string keys from the start)?

Answer

wyattisimo picture wyattisimo · Aug 20, 2012

The JSON generator converts symbols to strings because JSON does not support symbols. Since JSON keys are all strings, parsing a JSON document will produce a Ruby hash with string keys by default.

You can tell the parser to use symbols instead of strings by using the symbolize_names option.

Example:

original_hash = {:info => [{:from => "Ryan Bates", :message => "sup bra", :time => "04:35 AM"}]}
serialized = JSON.generate(original_hash)
new_hash = JSON.parse(serialized, {:symbolize_names => true})

new_hash[:info]
 #=> [{:from=>"Ryan Bates", :message=>"sup bra", :time=>"04:35 AM"}]

Reference: http://www.ruby-doc.org/stdlib-1.9.3/libdoc/json/rdoc/JSON.html#method-i-parse