Ruby 1.9 以降で JSON を扱う
Ruby で JSON を扱いたいと思って調べてみると、 Ruby 1.9 で標準添付ライブラリに加わったということを知ったのですが、いまいち情報がみつからなかったのでまとめてみました。
(追記) 1.9 の json ライブラリは gem の json パッケージのものと同じものみたいです(バージョンの差はあるかもしれませんが)。ちゃんと調べてませんが 1.9 の段階で既存のパッケージが取り込まれたかたちなのだと思います。ですので、以下は Ruby 1.8 系統に rubygems で json をいれたときでも同様の操作で JSON を扱えるはずです。
JSON からオブジェクトに
JSON 形式の文字列から配列/ハッシュへ
JSON から配列/ハッシュへは JSON.parse(str)
もしくは JSON.load(str)
で変換できます。
require 'json' JSON.parse('[1, 2, 3]') #=> [1, 2, 3] JSON.parse('{"foo" : "bar"}') #=> {"foo"=>"bar"}
ファイルから配列/ハッシュへ
JSON.load(io)
は文字列だけでなく IO から読み込んだものを変換することができます。
require 'json' # file.json には [1, 2, 3, {"foo" : "bar"}] と書かれているとき open("file.json") do |io| JSON.load(io) #=> [1, 2, 3, {"foo"=>"bar"}] end
変換した各オブジェクトを手続きとして処理する
JSON.load(str_or_io, proc)
の第二引数に手続きオブジェクトが与えられると、変換したオブジェクトを引数に手続きを呼び出すことができます。
require 'json' JSON.load('[1, 2, 3, {"foo" : "bar"}]', proc{|v| p v}) #=> [1, 2, 3, {"foo"=>"bar"}] # 以下が表示される # 1 # 2 # 3 # "foo" # "bar" # {"foo"=>"bar"} # [1, 2, 3, {"foo"=>"bar"}]
オブジェクトから JSON に
配列/ハッシュから JSON 形式の文字列へ
逆に配列ないしはハッシュから JSON へ変換するには JSON.generate(obj)
を使います。
require 'json' JSON.generate({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"
その他のオブジェクトから JSON で使える文字列へ
多くのクラスにも #to_json
が定義されています。
require 'json' 1.to_json #=> "1" Time.local(2011, 12, 5, 7, 29, 33).to_json #=> "\"2011-12-05 07:29:33 +0900\""
きれいに整形する
JSON.pretty_generate(obj)
は複数の行を使って、更に読みやすい形式で生成します。
require 'json' data = [1, 2, 3, {"foo" => "bar"}] JSON.generate(data) #=> "[1,2,3,{\"foo\":\"bar\"}]" JSON.pretty_generate(data) #=> "[\n 1,\n 2,\n 3,\n {\n \"foo\": \"bar\"\n }\n]"
配列/ハッシュからファイルへ
JSON.dump(obj, io)
を使うと書き込みモードの IO に、生成した JSON を書き込むことができます。
require 'json' open("file.json", "w") do |io| JSON.dump([1, 2, 3, {"foo" => "bar"}], io) # file.json に [1,2,3,{"foo":"bar"}] と書き込まれる end
そのほか
もっと簡潔に変換する
JSON[str_or_obj]
を使うと、引数が文字列のときは JSON.parse
、配列/ハッシュのときは JSON.generate
として処理されます。
require 'json' JSON['[1, 2, 3, {"foo":"bar"}]'] #=> [1, 2, 3, {"foo"=>"bar"}] JSON[[1, 2, 3, {"foo"=>"bar"}]] #=> "[1,2,3,{\"foo\":\"bar\"}]"
オプションとその他の情報について
JSON.parse(str, opts)
など第二引数などでオプションをとるものもあります。
require 'json' JSON.parse('{"foo":"bar"}') #=> {"foo"=>"bar"} JSON.parse('{"foo":"bar"}', {:symbolize_names => true}) #=> {:foo=>"bar"}
詳細についてここでは省きます。詳しくは以下のページやソース内のコメントを確認してください(ソース内でしか載っていないものもあります)。