JSONのキーは文字列

id:bluegale:20100610 で、

さて、では、この Hash を JSON形式に変換してあげるとどうなるでしょうか?

require "rubygems"  if(RUBY_VERSION < '1.9.1')
require "json"

test4hash = {nil => "nil!", "" => "empty!"}

p test4hash.to_json # => "{\"\":\"nil!\",\"\":\"empty!\"}"

JSON 形式の String に変換されましたね。

ふむふむ。

これを Parse するとどうなるでしょう?

require "rubygems"  if(RUBY_VERSION < '1.9.1')
require "json"

test4hash = {nil => "nil!", "" => "empty!"}

p JSON.parse(test4hash.to_json) # => "{\"\"=>\"empty!\"}"

となり nil, ""(空文字) 共に同じ key と見なされ 内容が上書きされたような感じでしょうか?

これの原因としては、

  • RubyではHashのキーは任意のオブジェクトが使えるが、JSONのキーは文字列のみ
  • JSONではキーの重複が許されるが、RubyのHashでは許されない

ということからでしょうか。
同じ事は、{1=>"one","1"=>"ichi"} 等でも起こる。

キーに文字列以外が使われているHashを to_json するとエラーになるという仕様にすれば防げるけど、使いにくくてしょうがない気がする。


JSONでも値の方は、null も使えるので、これはRuby側では nilマッピングされてますね。


そう言えば、nil.to_s を "" でなく "nil" にする案もあったようだ。"" との衝突の問題が、"nil" との衝突の問題に変わるだけで、上記の問題の解決にはならないが。