2013-04-24 4 views
3

Я не уверен в значении «... но не объекты, которые они ссылаются» как в документе, оформленном ruby, так и rubinus.Как понять, что #dup и #clone работают с объектами, ссылающимися на другие объекты?

В ruby-doc, есть объяснение #clone и #dup поведения говорят:

Производит неполную копию OBJ-переменные экземпляра OBJ будут скопированы, но не объекты, на которые они ссылаются. Копирует замороженное и испорченное состояние объекта. См. Также обсуждение в разделе Объект # dup.

То же самое повторяется в реализации Rubinius:

Копии переменных экземпляра, но не рекурсивно копировать объекты они ссылаются. Копирует испорченность.

Я пробовал со следующим кодом, но поведение не в моих ожиданиях.

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 

ответ

3

В 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> 
+0

Я думаю, что второй 's1.a.object_id # => 7344240' должен быть' s2.a.object_id'. Все они ссылаются на один и тот же объект массива. – steveyang

+0

Итак, «... не рекурсивно копирует объекты, которые они ссылаются."означает, только скопировать референт (указатель), а не ссылку, не так ли? – steveyang

+0

@ steven.yang: Whoopss! Спасибо. – Linuxios

0

«? Равны» Проверки сравнения являются ли они точно тот же объект:

  • == проверяет, сравнения, равны ли два значения
  • EQL? проверяет, равны ли два значения одного и того же типа
  • равно? проверяет, являются ли две вещи одним и тем же объектом.

, например:

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

Как вы проверяете с помощью равны? он показывает, что копия не сделала объект с неинициализированным массивом, но сделало объект скопированного объекта тем же массивом, что и оригинал. Если рекурсивно копировали opjects s2.array будет иметь такое же содержание, как s1.array но был бы другой объект так:

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

Как это ответить на вопрос? – Linuxios

+0

Я отредактировал и добавил немного более подробно –

+0

Я расстегнул свой голос. – Linuxios

 Смежные вопросы

  • Нет связанных вопросов^_^