We recently ran into a weird JSON-related issue in Ruby, namely that to_json
and JSON.parse
are not symmetric.
irb(main):004:0> JSON.parse("hello".to_json) JSON::ParserError: 757: unexpected token at '"hello"' from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/json/common.rb:155:in `parse' from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/json/common.rb:155:in `parse' from (irb):4 from /usr/bin/irb:12:in `'
It turns out that JSON.parse
expects a valid JSON document, which is defined on json.org as follows:
JSON is built on two structures:
- A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
- An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
So a single JSON value will never be a valid JSON document. Toward this end, JSON.generate
is actually the symmetric function you are looking for – it only accepts hashes and arrays. to_json
can be used to convert single values, but it is often not what you are looking for.
Should you find yourself in a situation where you need to eval messy JSON, you can enable quirks_mode
on JSON.parse
, which will behave closer to your expectations
JSON.parse("hello".to_json, :quirks_mode => true) # => "hello"