Связывание / сопряжение переменных, и как контролировать или нарушать эти ссылки - PullRequest
1 голос
/ 23 декабря 2011

В Rails переменные кажутся связанными, т. Е. Если вы сделаете a = b, если вы измените b, вы также измените a.Кроме того, если вы измените a, вы также измените b.

Я пришел из необработанного программирования (FORTRAN и C: языки, связанные с аэрокосмическим пространством, все еще привязаны), так что это связывание переменных является новым для меня.Кроме того, у меня возникли некоторые проблемы, поэтому я ищу способ управления им.

Я хотел бы иметь возможность определить переменную в виде значения константы (или массива значений), идо тех пор, пока я не переопределю его, оставлю его постоянным.Более конкретно, если я сделаю:

a = b

И затем я хочу переопределить

b = q

Я бы хотел, чтобы a сохранилисходное значение b (назовите его b '), в то время как новый b имеет значение q.

a = b'

b = q

a = b '! = b= q

Посмотрите на скрипт ниже с консоли rails, чтобы дополнительно проиллюстрировать вышеупомянутое связывание переменных.Вы можете сказать, что две переменные являются взаимозависимыми: вы не можете изменить одну, не изменяя другую.Любая помощь, контролирующая это явление, или просто ссылки на то, где я могу узнать о нем больше, была бы более ценной.

system :004 >   b = []
 => [] 
system :005 > b = [123,456]
 => [123, 456] 
system :006 > a = b
 => [123, 456] 
system :007 > a
 => [123, 456] 
system :008 > b
 => [123, 456] 
system :009 > b[0]
 => 123 
system :010 > b[0]=789
 => 789 
system :011 > a
 => [789, 456] 
system :012 > b
 => [789, 456] 
system :013 > a[0] = 0
 => 0 
system :014 > a
 => [0, 456] 
system :015 > b
 => [0, 456] 
system :016 > 

1 Ответ

0 голосов
/ 23 декабря 2011

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

В этом ответе: Назначение объектов и указатели кто-то рассказывает, как «назначение никогда не делает копию в ruby, но методы часто возвращают новые объекты вместо изменения существующих объектов».

Краткий ответ: чтобы убедиться, что вы создаете новый объект (т. Е. Не новый указатель на тот же объект), сделайте следующее:

 b = a.dup
...