Reputation: 13
I'm writing a method that modifies an array in a temporary variable and then pushes that variable into a multidimensional array. But when I push the temp variable into the multidimensional array, all the contents get overwritten with the value of temp. This is the method:
def possible_moves(start, moves = [])
return if start.any?(nil)
temp = []
# add 2 to first, add 1 to last
temp << start.first + 2
temp << start.last + 1
moves << temp
# add 2 to first, subtract 1 to last
temp.pop
temp << start.last - 1
moves << temp
moves
end
If I run the method with start = [3, 4]
then the result is
moves = [[5, 3], [5, 3]]
when the expected result should be
moves = [[5, 5], [5, 3]]
Also, using Array#push
instead of Array#<<
gives the same result.
I'm very new to programming and am having a hard time figuring out what's happening and how to solve it, so any help is very much appreciated. I'm working with Ruby 2.7.0.
Upvotes: 1
Views: 266
Reputation: 2434
def possible_moves(start, moves = [])
return if start.any?(nil)
temp = []
# add 2 to first, add 1 to last
temp << start.first + 2
temp << start.last + 1
moves << [*temp]
#or moves << temp.dup
# add 2 to first, subtract 1 to last
temp.pop
temp << start.last - 1
moves << [*temp]
#or moves << temp.dup
moves
end
The reason of above behaviour is due to the fact that when you push one array into another then pushed array is not copied , instead it's reference is copied so when you change the source array. Its value in other array changes. Here is a simple illustration to show that
ar1 = [1,2,3]
ar2 = [ar1,[5,6]] # [[1, 2, 3], [5, 6]]
ar1[0] = 99
now check ar2 , it would be [[99, 2, 3], [5, 6]]
You can verify it by checking object_id
of any ruby object
ar1.object_id
=> somenumber
ar2[0].object_id
=> samenumberagain
Upvotes: 1