1

我想在 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 对象?

4

2 回答 2

2

JSON 只是文本 - 在这种情况下,假定对象可以通过 JSON 序列化来回往返。

Object->JSON(Text)->Object因此,获得真正深层克隆的最简单方法;或者,反序列化 JSON 两次(一次用于深​​度克隆,因为两个反序列化在依赖对象图中产生)。请注意,这里的 Object不是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不做这个序列化/反序列化步骤,而只是归因于浅层 Object#clone 语义(实际上,没有 Hash#clone,所以它直接使用 Object#clone 的实现):

产生 obj 的浅拷贝——拷贝obj 的实例变量,但不拷贝它们引用的对象。

于 2013-09-06T01:22:18.460 回答
0

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

https://rubygems.org/gems/deep_dive

于 2014-01-19T19:53:29.400 回答