我想将Ruby中的嵌套数据结构转储到json(我知道Marshal模块,但我需要标准格式),并且能够再次加载/解析该数据结构。捕获:我将结构(或更简单的示例:哈希)用作哈希键。示例:
require 'json'
h = {{hello: 123} => 123}
JSON.parse(JSON.generate(h)) #=> {"{:hello=>123}"=>123}
问题是,JSON.generate(h)将键{:hello => 123}序列化为字符串,当我再次解析结果时,它仍然是字符串。
如何解决此问题并在生成/解析后重新获得原始结构?
答案 0 :(得分:3)
JSON仅允许将字符串用作对象键。因此,所有键都调用 to_s 。
您将有以下选择来解决您的问题:
最好的选择是更改数据结构,以便可以将其正确序列化为JSON。
您必须亲自处理该字符串化密钥。当哈希转换为可以使用Kernel#eval之类的字符串Andrey Deineko suggested in the comments进行转换时,散列会产生完全有效的Ruby语法。
result = json.transform_keys { |key| eval(key) }
# json.transform_keys(&method(:eval)) is the same as the above.
Hash#transform_keys方法是相对较新的(从Ruby 2.5.0开始可用),当前可能不在您的开发环境中。您可以根据需要用简单的Enumerable#map替换它。
result = json.map { |k, v| [eval(k), v] }.to_h
注意::如果传入的JSON包含我强烈建议的任何用户生成的内容,则不要使用 eval ,因为您可能允许用户在服务器上执行代码。