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).
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}"