JSON is merely text - and in this case it is assumed that the object can round-trip through JSON serialization.
Thus the simplest approach to go Object->JSON(Text)->Object
to obtain a true deep clone; alternatively, deserialize the JSON twice (once for the deep clone, as the two deserializations produce in dependent object graphs). Note that Object here is not JSON, but merely the deserialized representation (e.g. Hashes and Arrays) of the data as a standard Ruby objects.
# 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)
As noted, clone
does not do this serialization/deserialization step, but merely ascribes to shallow Object#clone semantics (actually, there is no Hash#clone, so it uses Object#clone's implementation directly):
Produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference ..