2015-05-22 8 views
0
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

Что мне не хватает?

.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.

EDIT: На самом деле, here ссылка на визуализации вашего кода, переписанного в Python - вы можете пошагово и точно узнать, что происходит. Затем замените строку добавления на path_locations.append([last_dest[0], last_dest[1]]), что именно вы сделали (и именно то, что Ruby's clone делает более сурово) и посмотреть, как она меняет программу.

Смежные вопросы