防止此变量发生变化

时间:2015-07-17 16:29:11

标签: ruby

我正在做一个单词问题。我想设置两个数组。一个用作基准(在迭代期间不会改变),其他在迭代期间发生变化。这是一个例子:

seed = 1
a = [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1]]
bm = a[seed]
a[seed].each.with_index do |x, i|
  if bm.include?(0)
    a[seed][i] = "WRONG"
  else
    a[seed][i] = 0 unless i == 3
  end
end

a #         => [[1, 1, 1, 1], [0, "WRONG", "WRONG, "WRONG"], [1, 1]]
# Should be => [[1, 1, 1, 1], [0, 0, 0, 1], [1, 1]]
bm #        => [0, "WRONG", "WRONG, "WRONG"]
# Should be => [1, 1, 1, 1]

通常情况下,如果您希望在"之前和之后#34;在您的代码中,您可以这样做:

a = 5
b = a
a = 6
a # => 6
b # => 5

在这种情况下,b更改后,它不会更改a。为什么会这样?我怀疑它是因为第二个例子是将数字存储为b,而在第一个例子中,它只存储代码。我该怎么做才能解决这个问题?这是不好的做法吗?

1 个答案:

答案 0 :(得分:1)

你是对的。当您将数组分配给bm时,您确实将a[seed]的引用(或指针,不确定Ruby更喜欢调用它)分配给object_id。您可以通过打印出两个变量的> a[seed].object_id => 70347648205960 > bm.object_id => 70347648205960 来看到这一点:

dup

请注意,它们指向同一个内部对象。解决方案是使用bm2复制数组并将新数组分配给> bm2 = a[seed].dup => [1, 1, 1, 1] > bm2.object_id => 70347649948520

> a[seed][0] = 'WRONG'
=> "WRONG"
> a[seed]
=> ["WRONG", 1, 1, 1]
> bm
=> ["WRONG", 1, 1, 1]
> bm2
=> [1, 1, 1, 1]

注意object_id已更改。现在,如果我做出改变......

object_id

您可能希望Google阅读有关dupcloneLink enabled, or的内容,该内容与dup相似,但有一些差异。