ruby中的意外返回值

时间:2015-05-22 00:27:41

标签: arrays ruby variable-assignment

def gen_path_locations(start, destination)
    initial_dest = destination
    last_dest = destination
    path_locations = []
    loop do
        last_dest[0] -= 1 if initial_dest[0] > start[0]
        last_dest[0] += 1 if initial_dest[0] < start[0]
        last_dest[1] -= 1 if initial_dest[1] > start[0]
        last_dest[1] += 1 if initial_dest[1] < start[0]
        break if last_dest == start
        path_locations << last_dest
        puts last_dest.inspect
    end
    path_locations
end

gen_path_locations([5, 5], [9, 9])返回[[5, 5], [5, 5], [5, 5]]

它将起始位置添加到我的path_locations而不是last_dest的当前迭代。当然,如果我将推送更改为:

path_locations << [last_dest[0], last_dest[1]]

返回预期值。我错过了什么?

1 个答案:

答案 0 :(得分:1)

  

我错过了什么?

A .clone

path_locations << last_dest.clone

否则,您将继续添加其内容不断变化的同一对象;最后,你仍然会有三次相同的对象,其内容是你改变它的任何内容。

以下是一个例子来说明:

a = ["foo", "bar"]
b = [a, a, a]
# => [["foo", "bar"], ["foo", "bar"], ["foo", "bar"]]
a[1] = "quux"
b
# => [["foo", "quux"], ["foo", "quux"], ["foo", "quux"]]

您可以看到正在发生的事情here。该工具不适用于Ruby,但很高兴该示例也适用于Python。

编辑:实际上,here您的代码可视化的链接,重写为Python - 您可以逐步查看确切的内容。然后用path_locations.append([last_dest[0], last_dest[1]])替换附加行,这正是你所做的(确切地说Ruby的clone更加简洁),并看看它如何改变程序。