シリアル化されたJSON文字列(実際にはシェフの役割の定義)があり、json_classキーがあり、rubyJSONパーサーがそれをChef::Roleオブジェクトに強制しようとします。パーサーにこのキーを無視させ、単に通常のハッシュに逆シリアル化するにはどうすればよいですか?
4 に答える
同じ問題が発生し、JSON gemのソースを読み取って答えを見つけました。解析を実行する前に、JSON.create_idの設定を解除してください。
JSON.create_id = nil
JSON.parse('{ "json_class": "Chef::Role" }').class => Hash
編集: gemのバージョン1.7(このアップデートを入力すると1.8.0が最新)なので、上記のハックは不要になりました。 JSON#parse
を無視するようjson_class
になりJSON#load
ました。代わりに、ダンプされたオブジェクトのマーシャリングを解除するために使用する必要があります。
「json_class」キーは、json をアンマーシャリングするオブジェクトを示すためにあります。JSON.dump によって追加されます。JSON の最近のバージョンでは、JSON.parse
"json_class" を無視し、ハッシュにマーシャリング解除します。JSON.load
指定されたオブジェクト(あなたの場合、Chef::Role)にアンマーシャリングします。
JSON.parse('{ "json_class": "Chef::Role" }').class => Hash
JSON.load('{ "json_class": "Chef::Role" }').class => Chef::Role
解析する前に文字列に対して aを実行し、その特定のキーを別のものに変更できます。gsub
前後の JSON のサンプルを示してみてはどうでしょうか。
ドキュメントによると、Mark Reed のソリューションは確かに機能するはずです。しかし、Vagrantfileでこれを試したとき:
JSON.create_id = nil
vagrant_json = JSON.parse(Pathname(__FILE__).dirname.join('nodes', "#{node_name}.json").read)
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = "roles"
chef.data_bags_path = "data_bags"
chef.node_name = node_name
chef.run_list = vagrant_json.delete('run_list')
chef.json = vagrant_json
end
vagrant_json.class はハッシュでしたが、node.json ファイルに"json_class": "Chef::Node"エントリが含まれている場合は常に json_class 値を内部的に保持していました。次に、最後の行でハッシュを使用してchef.jsonの値を設定すると、jsonクラスを使用して再び解釈されました(奇妙なことに、結果は空の実行リストでした)。
これが機能したものです。同じアイデアですが、フィネスが少し劣ります:
vagrant_json = JSON.parse(Pathname(__FILE__).dirname.join('nodes', "#{node_name}.json").read)
vagrant_json['json_class'] = nil # <== This worked
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = "roles"
chef.data_bags_path = "data_bags"
chef.node_name = node_name
chef.run_list = vagrant_json.delete('run_list')
chef.json = vagrant_json
end
このコードは、 "json_class": "Chef::Node"エントリの有無にかかわらず、Chef ノード ファイルから json 属性と実行リストの両方を設定するために機能しました。
要約すると、前の回答は JSON.parse からハッシュを取得することに関しては完全に正しいように見えますが、そのハッシュから json_class ペアを削除しないと、この場合のように後で問題が発生する可能性があります。