Ruby の Hash で JSON

仕事の関係で、JSON に絡む開発を手伝っています。
しかし、開発中の Web Server から 受け取った JSON に問題があり、途中でデータが化ける事がようで
それの確認用のスクリプトをいろいろ考えているときに思った事
もしくは、自分用 memo として、少しばかり。


あまり気にしていなかったのですが、Hash の key って ""(空文字) や nil でも良いんですね…。

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


p test4hash # => {nil=>"nil!", ""=>"empty!"}
p test4hash.keys # => [nil, ""]


p test4hash[nil] # => "nil!"
p test4hash[""] # => "empty!"

このように、普通に Hash として使えます。
# へー。(とは言え、今のところ あまり積極的に使う気は無いなぁ…。w)




さて、では、この 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 と見なされ 内容が上書きされたような感じでしょうか?
まぁ、JSON で Object のやり取りなど期待していないので、できると思っていませんが
nil, ""(空文字) 共に、バグのポイントになりそうなので、少し注意が必要な気がしてきます。


ちなみに、無理やり Object を JSON に変換した場合の例も。

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

test4hash = {Time.now => "Time!", Class.new => "Class!"}


p test4hash.to_json # => "{\"2010-06-10 13:09:02 +0900\":\"Time\",\"#\":\"class!\"}"

となる事から、Hash の key は JSON に変換する際に、文字列変換しているんでしょうね。
なるほど…。