Reputation: 135
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])
returns [[5, 5], [5, 5], [5, 5]]
It adds the starting location to my path_locations instead of the current iteration of last_dest. Of course, if I change the push over to this:
path_locations << [last_dest[0], last_dest[1]]
It returns the expected values. What am I missing?
Upvotes: 0
Views: 74
Reputation: 198324
What am I missing?
A .clone
:
path_locations << last_dest.clone
Otherwise, you keep adding the same object whose contents you keep changing; in the end, you will still have the same object three times, whose contents are whatever you changed it to last.
Here's an example to illustrate:
a = ["foo", "bar"]
b = [a, a, a]
# => [["foo", "bar"], ["foo", "bar"], ["foo", "bar"]]
a[1] = "quux"
b
# => [["foo", "quux"], ["foo", "quux"], ["foo", "quux"]]
You can see what is happening here. The tool is not for Ruby, but happily the example works in Python as well.
EDIT: Actually, here is the link to visualisation of your code, rewritten into Python - you can step through and see exactly what is happening. Then replace the append line with path_locations.append([last_dest[0], last_dest[1]])
, which is exactly what you did (and exactly what Ruby's clone
does more succintly), and see how it changes the program.
Upvotes: 1