Как работает оператор присваивания в Ruby?

#ruby #variable-assignment

#ruby #переменная-присваивание

Вопрос:

Я пишу простой фрагмент кода на ruby, но он работает совсем не так, как я ожидаю. Я думаю, что эта проблема возникает из-за непонимания того, как работает ruby, в частности, как работает оператор присваивания, относительно других языков. Вот что я написал:

     @instance1 = @clock
    @clock.tick!
    @clock.tick!
    @clock.tick!
    @instance2 = @clock

    puts " instace1.seconds: #{@instance1.seconds}, instance2.seconds: #{@instance2.seconds}"
  

‘Clock’ — это класс, имеющий значение seconds, метод ‘tick!’, который увеличивает секунды на единицу, и метод ‘seconds’, который возвращает значение seconds. Секунды инициализируются как 0.

Теперь, когда я запускаю этот код, вывод: » instace1.seconds: 3, instance2.seconds: 3″

Но я ожидаю, что результат будет следующим: » instance1.seconds: 0, instance2.seconds: 3″

Потому что я присвоил intance1 значения, которые были у @clock до того, как я изменил clock , и я ничего не сделал для изменения @instance1 после этого.

Для меня это означает, что ruby присваивает объекты в качестве указателей в некоторых контекстах и что происходит неявное разыменование. Что это за контексты? (переменные класса?, большие объекты? )

Как мне выполнить явное присвоение? Другими словами, как мне разыменовать переменную?

Например, в C я бы сделал что-то вроде:

 *instance1 = *c
  

(хотя прошло много времени с тех пор, как указатель-арифметический, так что это грубый пример

Ответ №1:

Ruby присваивает по ссылке, а не по значению. Что вы можете сделать, так это @instance1 = @clock.dup или @instance1 = @clock.clone .

Комментарии:

1. Но прежде чем вы должны убедиться, что класс Clock реализует #dup или #clone . К сожалению, Ruby не будет выполнять глубокое клонирование для вас.