3

Anyone else having this issue?

hash_as_key = {'one' => 1, 'two' => 2}
outer_hash = {hash_as_key => 3} 

outer_hash.keys[0].class
=> Hash

as_json = outer_hash.to_json
back_to_obj = JSON.parse(as_json)

back_to_obj.keys[0]
=> "{\"one\"=>1, \"two\"=>2}"
back_to_obj.keys[0].class
=> String

If you have a Hash object where a key is a hash itself, converting to JSON and reverting back to a Ruby object seems to turn the key into a String.

4

1 回答 1

3

The keys in JSON objects are strings and nothing else:

An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

enter image description here

So your keys will become strings as soon as your data structure is converted to JSON. Then, once your data is in JSON, the original type information for your keys will be lost.

Ruby's Hashes are a fair bit more flexible and general than JSON's objects so not every Ruby Hash can be represented in JSON. If you're targeting JSON for data storage and transfer, then you'll have to limit your data to things that JSON supports or translate your data into a structure that is JSON-compatible.

If you look at the intermediate JSON you'll see what's going on:

> puts outer_hash.to_json
{"{\"one\"=>1, \"two\"=>2}":3}

So the key is the string '{"one"=>1, "two"=>2}' because that's what hash_as_key.to_s gives you. Similarly, a numeric key will be stringified with to_s and lose its "numberness":

> {1 => 2}.to_json
=> "{\"1\":2}" 
于 2012-11-08T08:00:40.593 回答