I am not sure about the meaning of "...but not the objects they reference" in both the documantion of ruby
and rubinus
.
In ruby-doc, there is the explanation of #clone
and #dup
behavior saying:
Produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference. Copies the frozen and tainted state of obj. See also the discussion under Object#dup.
The same is repeated in the implementation of Rubinius:
Copies instance variables, but does not recursively copy the objects they reference. Copies taintedness.
I tried out with the following code, but the behavior is out of my expectation.
class Klass
attr_accessor :array
end
s1 = Klass.new
ar = [1, 2, 3]
s1.array = [ar]
s2 = s1.clone
# according to the doc,
# s2.array should be initialized with empty Array
# however the array is recursivley copied too
s2.array.equal? s1.array # true
The "equal?" comparison checks whether they are exactly the same object:
for example :
As you are testing using equal? it shows the copy has not made an object with the array being uninitialized, but it has made the copied object point to the same array as the original. If it recursively copied the opjects s2.array would have the same contents as s1.array but would be a different object so:
In Ruby, all objects are references. Take a look at the following example:
You can see that both of the arrays are the same object, and are both references to the array living somewhere in the heap. In a deep copy, the array itself would have been copied, and the new
s2
would have its own, distinct array. The array is not copied, just referenced.Note: Here's what it looks like if you do a deep copy: