2016-11-17 3 views
0

У меня возникли некоторые проблемы с пониманием концепции мелкой копии и метод #dupДействительно ли создается мелкая копия?

У меня есть этот код

class MyObject 
end 

myObject1 = MyObject.new 
myObject2 = MyObject.new 

Я знаю, что это будет печатать ложь потому что я буду испытывать для объекта равенства, а не равенство значений

p myObject1 == myObject2 

Но согласно definition пологой копии

.dup производит неглубокую копию obj - переменные экземпляра obj копируются, но не объекты, которые они ссылаются.

Я ожидал, что это печать верно, но он также печатает ложные

p myObject1 == myObject1.dup 

Не является ли определение неправильно то? Не должно myObject1.dup a instance variable, которое указывает на тот же объект, что и myObject1, за исключением явно нет?

ответ

1

Вы забыли, что == на самом деле метод из BasicObject:

OBJ == другого → истинного или ложного
равенства - на уровне объекта, == возвращается true только если obj и другие являются тот же объект. Как правило, этот метод переопределяется в классах потомков, чтобы обеспечить значение, специфичное для класса.

Так что, если вы не предоставите свою собственную реализацию == (т.е. MyObject#== метод), то ваш:

p myObject1 == myObject1.dup 

является в значительной степени то же самое, как говорят:

p myObject1.object_id == myObject1.dup.object_id 

и поскольку myObject1.dup является мелкой копией myObject1 (т.е. они разные объекты), вы получаете false.

Когда они говорят:

переменные экземпляра obj копируются

они со ссылкой на переменные экземпляра внутриobj, а не переменные, которые происходят ссылаться obj. Ваш myObject1 не является переменной экземпляра во всем, это просто переменная, переменные экземпляра ссылаются на ведущий @, как в @my_instance_variable.

Если вы хотите == вести себя они, как вы ожидаете его, то вы должны предоставить собственный == реализации:

class MyObject 
    def ==(other) 
    # Check that the contents of `self` and `other` are the same 
    # and probably that `other.is_a?(MyObject)` first. 
    end 
end 
+0

Не совсем то, что я просил. То, что я хотел сказать, не означает, что это определение '.dup создает мелкую копию obj - копии экземпляров obj копируются, но не объекты, которые они ссылаются. 'Подразумевают, что' p myObject1 == myObject1.dup' должен print true? В основном, язык заставляет его звучать как '.dup' дублирует указатели, но они все же указывают на один и тот же объект. Получите то, что я прошу сейчас? –

+0

О боже, я идиот. Большое спасибо! –

+1

Но 'myObject' - это просто переменная (не переменная экземпляра), и в документации говорится, что' dup' копирует переменные экземпляра * внутри * 'obj'. 'myObject1' и' myObject1.dup' - совершенно разные объекты, и вы не предоставляете свой собственный '==', поэтому 'myObject1 == myObject1.dup' является' false'. Я также добавил немного разъяснений к моему ответу, поэтому я просто проигнорирую этот идиотский бит. –

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