ruby / json

JSON implementation for Ruby
https://ruby.github.io/json
Other
673 stars 326 forks source link

JSON additions do not recurse #568

Closed mperham closed 7 months ago

mperham commented 7 months ago

This seems inconsistent and not useful. I want Symbols to serialize the same everywhere. Am I missing something?

> require "json/add/core"
=> true
> JSON.generate(:foo)
=> "{\"json_class\":\"Symbol\",\"s\":\"foo\"}"
> JSON.generate({:foo => "mike"})
=> "{\"foo\":\"mike\"}"
mperham commented 7 months ago

The round trip isn't symmetric. How can I get symmetric dump/parse?

# current
> JSON.parse JSON.generate(:foo)
=> {"json_class"=>"Symbol", "s"=>"foo"}

# ideal
> JSON.parse JSON.generate(:foo)
=> :foo
mperham commented 7 months ago

Ah, ok:

> JSON.parse JSON.generate(:foo), create_additions: true
=> :foo

Still need support for Hash and recursive structures.

mperham commented 7 months ago

Looks like it's only an issue with Hash keys. Works with Arrays and Hash values.

> JSON.parse(JSON.generate([1, [:foo, "mike"]]), create_additions: true)
=> [1, [:foo, "mike"]]
> JSON.parse(JSON.generate({:foo => "mike", 123 => :bar}), create_additions: true)
=> {"foo"=>"mike", "123"=>:bar}

But unfortunately Hash keys are the main usecase for Symbols in method arguments.

mperham commented 7 months ago

I think I understand now. "JSON keys are strings, always on the left of the colon, and must be wrapped in double quotes". Converting a Symbol to a Hash is ok but it can't be used as a key in a larger Hash. The code would need to be modified to perform something similar to ActiveJob here:

https://github.com/rails/rails/blob/3ecc26981476d6a8c4f1ba5bd33bfdeef1659a0f/activejob/lib/active_job/arguments.rb#L92C1-L101C1