如何让 Ruby JSON 解析器忽略 json_class?
我有一个序列化的 JSON 字符串(实际上是 Chef 角色定义),它有一个 json_class 键,使 ruby JSON 解析器尝试强制它成为 Chef::Role 对象。如何让解析器忽略这个键并简单地反序列化为正常的哈希值?
I have a serialized JSON String (chef role definition actually) and it has a json_class key, making the ruby JSON parser try to force it to be a Chef::Role object. How can I make the parser ignore this key and just simply deserialize into a normal Hash?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我刚刚遇到了同样的问题,并通过阅读 JSON gem 的源代码找到了答案 - 只需在尝试进行解析之前取消设置 JSON.create_id:
编辑: 请注意,自 gem 版本 1.7 以来(当我输入此更新时,1.8.0 是最新的),不再需要上述 hack。
JSON#parse
现在忽略json_class
,并且应使用JSON#load
来解组转储对象。I just had the same problem, and found the answer by reading the source of the JSON gem - just unset JSON.create_id before trying to do the parse:
EDIT: Note that since version 1.7 of the gem (1.8.0 is current as I type this update), the above hack is no longer necessary.
JSON#parse
now ignoresjson_class
, andJSON#load
should be used instead for unmarshalling dumped objects.“json_class”键用于指示 json 应该被解组为哪个对象。它是通过 JSON.dump 添加的。在 JSON 的最新版本中,
JSON.parse
将忽略“json_class”,解组为哈希。而JSON.load
将解组到指定的对象(在您的情况下,为 Chef::Role)。The "json_class" key is there to indicate what Object the json should be un-marshaled as. It is added by JSON.dump. In more recent versions of JSON,
JSON.parse
will ignore "json_class", un-marshaling to a Hash. WhileJSON.load
will un-marshal to the indicated Object (in your case, a Chef::Role).您可以在解析之前对字符串执行
gsub
,并将该特定键更改为其他内容。展示前后的 JSON 示例怎么样?
You could do a
gsub
on the string before parsing, and change that particular key to something else.How about showing a sample of the JSON before and after?
根据文档,马克·里德的解决方案当然应该有效。但是当我在 Vagrantfile 中尝试此操作时:
vagrant_json.class 是一个哈希,但每当 node.json 文件包含 "json_class": "Chef::Node" 时,它仍然在内部保留 json_class 值入口。然后,当使用哈希设置最后一行中的 Chef.json 值时,再次使用 json 类对其进行解释(奇怪的是,结果是一个空的运行列表。)
这是有效的。相同的想法,但技巧稍差一些:
此代码用于从 Chef 节点文件设置 json 属性和运行列表,无论有或没有 "json_class": "Chef::Node" 条目。
总之,关于从 JSON.parse 获取哈希,前面的答案似乎完全正确,但如果您不从该哈希中删除 json_class 对,以后仍然可能会出现问题,就像在本例中一样。
According to the docs, Mark Reed's solution should certainly work. But when I tried this in a Vagrantfile:
the vagrant_json.class was a Hash, but it still retained the json_class value internally whenever the node.json file contained the "json_class": "Chef::Node" entry. Then when using the hash to set the chef.json value in the last line, it was again interpreted using the json class (and the result was, oddly, an empty run list.)
Here's what worked. Same idea, but a bit less finesse:
This code worked to set both the json attributes and the run list from a Chef node file, with or without the "json_class": "Chef::Node" entry.
In summary, the previous answer does seem completely correct in relation to getting a hash from JSON.parse, but if you don't remove the json_class pair from that hash, there can still be trouble later, as in this case.