6

シリアル化されたJSON文字列(実際にはシェフの役割の定義)があり、json_classキーがあり、rubyJSONパーサーがそれをChef::Roleオブジェクトに強制しようとします。パーサーにこのキーを無視させ、単に通常のハッシュに逆シリアル化するにはどうすればよいですか?

4

4 に答える 4

13

同じ問題が発生し、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ました。代わりに、ダンプされたオブジェクトのマーシャリングを解除するために使用する必要があります。

于 2011-06-30T13:44:48.207 に答える
6

「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
于 2013-03-29T17:26:01.410 に答える
0

解析する前に文字列に対して aを実行し、その特定のキーを別のものに変更できます。gsub

前後の JSON のサンプルを示してみてはどうでしょうか。

于 2011-02-03T01:46:15.283 に答える
0

ドキュメントによると、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 ペアを削除しないと、この場合のように後で問題が発生する可能性があります。

于 2014-03-12T04:47:14.610 に答える