Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby中的深度复制JSON对象_Ruby_Ruby 1.9 - Fatal编程技术网

Ruby中的深度复制JSON对象

Ruby中的深度复制JSON对象,ruby,ruby-1.9,Ruby,Ruby 1.9,我想在Ruby中深度复制一个json对象。然而,当我调用clone这个json对象时,它似乎并没有进行深度复制。我是否可能或正在做错事。下面是我现在所做工作的相关代码片段: idFile = File.new(options[:idFile]) idFile.each_line do |id| jsonObj = getJson(id) copyObj = jsonObj.clone copyObj['details']['payload'] = Base64.decod

我想在Ruby中深度复制一个json对象。然而,当我调用clone这个json对象时,它似乎并没有进行深度复制。我是否可能或正在做错事。下面是我现在所做工作的相关代码片段:

idFile = File.new(options[:idFile])
idFile.each_line do |id|
    jsonObj = getJson(id)
    copyObj = jsonObj.clone
    copyObj['details']['payload'] = Base64.decode64(copyObj['payload'])
    copyObj['key'] = 1
    jsonObj['details']['payload'] = Base64.decode64(jsonObj['payload'])
    jsonObj['key'] = 2
    send(copyObj)
    send(jsonObj)  #error here
end

def getJson(id)
    idData = getData(id)
    idJson = JSON.parse!(idData)
    idJson = idJson['request'][0]
    return idJson
end
我的错误是由于解码调用而发生的。第一个解码调用已经对对象进行了解码,第二个解码调用尝试再次解码相同的数据,这在第二个发送调用中出错,因为此时数据是乱七八糟的。

如何深度复制json对象?

json仅仅是文本,在本例中,假设对象可以通过json序列化进行往返

因此,最简单的方法是使用
Object->JSON(Text)->Object
获得真正的深层克隆;或者,反序列化JSON两次(一次用于深度克隆,因为这两次反序列化在依赖对象图中产生)。请注意,这里的对象不是JSON,而是作为标准Ruby对象的数据的反序列化表示(例如哈希和数组)

# Standard "deep clone" idiom using an intermediate serialization.
# This is using JSON here but it is the same with other techniques that walk
# the object graph (such as Marshal) and generate an intermediate serialization
# that can be restored later.
jsonObj = getJson(id)
jsonObj["foo"] = "change something"
json = JSON.generate(jsonObj)
copyObj = JSON.parse(json)

# Or, assuming simple deep clone of original, just deserialize twice.
# (Although in real code you'd only want to get the JSON text once.)
jsonObj = getJson(id)
copyObj = getJson(id)
如前所述,
clone
不执行此序列化/反序列化步骤,而只是归因于(实际上,没有哈希克隆,因此它直接使用对象克隆的实现):

生成obj的浅层副本将复制obj的实例变量,但不会复制它们引用的对象


如果您只是想对任意Ruby对象进行深度复制,请尝试深度潜水


对不起,我不明白。getJson(id)调用执行JSON.parse!(txt)。这不应该返回ruby对象吗。文档中说“将JSON文档源解析为Ruby数据结构并返回它。”此时它已经是一个散列对象,我获取一个子散列对象并尝试克隆它。Ruby哈希支持根据文档进行克隆。如果我打印出类,它会输出散列。它会返回一个ruby对象。这就是为什么在第一个示例中,我们首先将其序列化回JSON(
JSON=JSON.generate..
),然后再对其进行反序列化。请注意,哈希支持克隆,但不支持深度克隆(
#clone
永远不应该是深度克隆!)。我建议的解决方案使用Obj->JSON->Obj作为克隆。另一种选择是使用Marshall,例如。请注意,这两种方法都首先生成一个中间文档。JSON或Marshall使用的内容。当然,这也可以递归完成。我理解这一部分。根据您的建议,我使用了JSON.parse(jsonObj.to_JSON)。。。这修正了我的错误,但这看起来很混乱。关于在ruby-1.9中深度复制散列对象,我缺少什么吗?谷歌到处搜索都说jsonObj.clone应该深度复制它。虽然我猜它的名称不正确,应该被称为hashObj,但对于这个问题…@Niru,找到的资源不正确,或者引用了一个扩展(例如)或其他不同的环境。Ruby 1.9.3中有一个漏洞,所以它遵从对象克隆,语义很浅。啊,对不起。。。。我没有完全阅读你的评论,现在我在结尾看到了那张浅薄的便条。谷歌搜索结果提到做马歇尔无论如何。。。看来我必须这么做。谢谢你的帮助!