How to understand the #dup and #clone operate on objects which referencing other objects?

我与影子孤独终老i 提交于 2019-12-01 10:38:44

In Ruby, all objects are references. Take a look at the following example:

class Klass
  attr_accessor :a
end

s1 = Klass.new
a = [1,2,3]
s1.a = a
s2 = s1.clone
s1.a.object_id  #=> 7344240 
s2.a.object_id  #=> 7344240 

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:

s3 = Marshal.load(Marshal.dump(s1)) #=> #<Klass:0x00000000bf1350 @a=[1, 2, 3, 4], @bork=4> 
s3.a << 5 #=> [1, 2, 3, 4, 5] 
s1 #=> #<Klass:0x00000000e21418 @a=[1, 2, 3, 4], @bork=4> 

The "equal?" comparison checks whether they are exactly the same object:

  • The == comparison checks whether two values are equal
  • eql? checks if two values are equal and of the same type
  • equal? checks if two things are one and the same object.

for example :

a=[1,2]
=> [1, 2] 
a == [1,2]
=> true 
a.eql? [1,2]
=> true 
a.equal? [1,2]
=> false 
a.equal? a
=> true

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:

s2.array.equal? s1.array # false
s2.array.eql? s1.array # true
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!