Ruby 如何理解#dup和#clone对引用其他对象的对象的操作?

Ruby 如何理解#dup和#clone对引用其他对象的对象的操作?,ruby,object,clone,dup,Ruby,Object,Clone,Dup,我不确定ruby和rubinus的文档中的含义,但不确定它们引用的对象“ 在中,对#clone和#dup行为的解释是: 生成obj的浅层副本obj的实例变量为 已复制,但未复制它们引用的对象。复制已冻结和 obj的污染状态。另请参见对象#dup下的讨论 在执行下列各项时也重复了这一点: 复制实例变量,但不递归复制对象 它们是参考文献。复制污染 我尝试了以下代码,但其行为超出了我的预期 class Klass attr_accessor :array end s1 = Klass.new

我不确定
ruby
rubinus
的文档中的含义,但不确定它们引用的对象“

在中,对
#clone
#dup
行为的解释是:

生成obj的浅层副本obj的实例变量为 已复制,但未复制它们引用的对象。复制已冻结和 obj的污染状态。另请参见对象#dup下的讨论

在执行下列各项时也重复了这一点:

复制实例变量,但不递归复制对象 它们是参考文献。复制污染

我尝试了以下代码,但其行为超出了我的预期

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

在Ruby中,所有对象都是引用。请看以下示例:

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 
您可以看到这两个数组都是同一个对象,并且都是对堆中某个位置的数组的引用。在深度复制中,数组本身将被复制,而新的
s2
将有其自己的独特数组。数组没有被复制,只是被引用

注意: 下面是进行深度复制时的情况:

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> 
s3=Marshal.load(Marshal.dump(s1))\
s3.a[1,2,3,4,5]
s1#=>#
比较“相等”检查它们是否完全相同:

  • ==比较检查两个值是否相等
  • eql?检查两个值是否相等且类型相同
  • 平等?检查两个对象是否为同一对象
例如:

a=[1,2]
=> [1, 2] 
a == [1,2]
=> true 
a.eql? [1,2]
=> true 
a.equal? [1,2]
=> false 
a.equal? a
=> true
当您使用equal进行测试时?它显示副本未使数组未初始化的对象,但已使复制的对象指向与原始对象相同的数组。如果它递归复制opjects s2.array,则其内容将与s1.array相同,但将是不同的对象,因此:

s2.array.equal? s1.array # false
s2.array.eql? s1.array # true

这是如何回答这个问题的?我认为第二个
s1.a.object_id#=>7344240
应该是
s2.a.object_id
。尽管它们引用了相同的数组对象。所以“…不会递归地复制它们引用的对象。”意思是,只复制引用器(指针),而不是引用,对吗?@steven.yang:Whoopss!谢谢。所以,我在问题中写的行为正是应该实现的。知道了。