我想深入复制Ruby中的json对象。但是,当我调用克隆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对象?
答案 0 :(得分:2)
JSON只是文本 - 在这种情况下,假设对象可以通过JSON序列化进行往返。
因此,最简单的方法是Object->JSON(Text)->Object
获得真正的深度克隆;或者,将JSON反序列化两次(一次用于深度克隆,因为两个反序列化在依赖对象图中产生)。请注意,此处的Object是不是 JSON,而只是数据的反序列化表示(例如Hashes和Arrays)作为标准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
不会执行此序列化/反序列化步骤,而只是归于shallow Object#clone semantics(实际上,没有Hash#clone,因此它使用了Object #cron的直接实现):
生成obj的浅拷贝 - 复制obj的实例变量,但不复制它们引用的对象。
答案 1 :(得分:0)
如果您只是想要对任意Ruby对象进行深层复制,请尝试使用deep_dive。