JSON.load
でJSON文字列をRubyのオブジェクトにしたいとき、ちょっぴりつまづいたのでメモ
以下はJSON文字列をloadしてRubyのオブジェクトに変換するコード例
str=<<JSON { "a":1, "b":2, "c":3 } JSON JSON.load(str) # => {"a"=>1, "b"=>2, "c"=>3} # 普通に渡すとキーが文字列になる
↑を:a
のようにキーをシンボルにしたい
ということでるりまを見ると、キーをシンボルにするオブションがあった。以下抜粋して引用。
:symbolize_names
真を指定するとハッシュのキーを文字列ではなくシンボルにします。デフォルトは偽です。
お、ということは、:symbolize_names
をtrue
にすれば良い??
やってみた💪🏻
JSON.load(str, symbolize_names: true) # => {"a"=>1, "b"=>2, "c"=>3} # おっと変わらないぞ?
あれ、変わらない。
もう一度るりまを見たら
load(source, proc = nil, options = {}) -> object
どうやらprocとoptionsはデフォルト引数になっているらしい。
と、いうことはoptions(今回で言えばsymbolize_names
)のデフォルトを書き換えたい場合は、その前の
第二引数でproc
について指定してあげないといけないのかなと思い、やってみる
JSON.load(str, nil, symbolize_names: true) # 第二引数のproc部分をnilにした # => (省略)`initialize': options :symbolize_names and :create_additions cannot be used in conjunction (ArgumentError) (省略)
なんかエラー出た!!
DeepL先生によると
initialize': オプション :symbolize_names と :create_additions は同時に使用できません (ArgumentError)
らしい。なんのこっちゃ🤔という感じなのでもう一度るりまを見る。
お、それっぽい記述があった!
:create_additions
偽を指定するとマッチするクラスや JSON.create_id が見つかっても付加情報を生成しません。デフォルトは真です。
「「「デフォルトは真。」」」
そして先ほどのエラー文訳、initialize': オプション :symbolize_names と :create_additions は同時に使用できません
ということは、:symbolize_names
と:create_additions
を今回どちらも真にしてしまったのがよくなかったらしい。
再チャレンジ!
JSON.load(str, nil, symbolize_names: true, create_additions: false) # => {:a=>1, :b=>2, :c=>3} # できた〜!
結論
JSON.load
でキーをシンボルにしたいときは
symbolize_names: true
とともに、
第二引数にprocについてを渡す(今回は
nil
):create_additions
は:symbolize_names
と共存できない(どちらもtrueはできない)そのため、
create_additions: false
も記述する
ちなみにJSON.parse
の場合
parse(source, options = {}) -> objectかつ
:create_additionsがデフォルトでfalse
なので、第二引数にsymbolize_names: true
を記述するだけでキーをシンボルにできる
JSON.parse('[1,2,{"name":"tanaka","age":19}]', symbolize_names: true) # => [1, 2, {:name=>"tanaka", :age=>19}]
JSON.load
とJSON.parse
は引数の書き方が違うということがわかった。
&無事キーをシンボルにできたのでヨシ☺️☺️!