Переопределение 2d массив переменных не работает в ruby? - PullRequest
1 голос
/ 05 марта 2011

Я не могу переопределить переменную в моем коде ruby.

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

почему это? очень простой пример того, что я пытаюсь сделать.

class SomeClass

  table = [[0,20,5,1000,1000], [20,0,10,8,20], [5,10,0,1000,40], [1000,8,1000,0,6], [1000,20,40,6,0]]
  updated_table = table
   ##
   then here i have some code that makes changes to the values in the updated_table
   ##  
   2.times do
     updated_table = table # this dosent work??
     ## do some more calculations and so on ##
   end
end

Ответы [ 3 ]

2 голосов
/ 05 марта 2011

В Ruby переменные не содержат сам объект. Говорят, они указывают на или ссылку на объект в памяти. Итак, когда вы пишете updated_table = table, вы не делаете копию объекта, вы просто создаете другую ссылку на этот объект.

Вы можете создать отдельный, но идентичный объект с помощью метода Object#dup.

updated_table = table.dup

Это мелкая копия из-за того, что массив содержит ссылки на объекты, и эти объекты сами не дублируются. Это означает, что и исходный массив, и дубликат фактически ссылаются на одни и те же элементы, поэтому имейте это в виду, если вам нужно изменить объекты, хранящиеся в любом из массивов.

2 голосов
/ 05 марта 2011

Вы сделали updated_table ссылкой на table, когда позвонили updated_table = table. Они оба указывают на одну и ту же таблицу. Когда вы изменили updated_table, вы одновременно обновили table.

Я верю, что ты хочешь updated_table = table.dup.

1 голос
/ 05 марта 2011

Будет ли глубокое копирование достичь желаемого результата?

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

Я не думаю, что object.dup будет работать так, как вы хотите, потому что ваш массив является двухмерным. Смотрите здесь - http://ruby.about.com/od/advancedruby/a/deepcopy.htm - для хорошего дальнейшего чтения (с примерами на основе массива) на предмет object.dup, клонирования и сортировки, чтобы выяснить, почему.

Я просто добавил фрагмент для глубокого копирования таблицы, а не клонировал ее.

# Deep copy - http://www.ruby-forum.com/topic/121005
# Thanks to Wayne E. Seguin.
class Object
   def deep_copy( object )
     Marshal.load( Marshal.dump( object ) )
   end
end

table = [[0,20,5,1000,1000], [20,0,10,8,20], [5,10,0,1000,40], [1000,8,1000,0,6],     [1000,20,40,6,0]]

updated_table = deep_copy(table) # -- DON'T CLONE TABLE, DEEP COPY INSTEAD --

##
# then here i have some code that makes changes to the values in the updated_table
##  
2.times do
    updated_table = deep_copy(table) # -- USE DEEP_COPY HERE TOO --
    ## do some more calculations and so on ##
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...