Oleg  Sobchuk Oleg Sobchuk - 3 months ago 24
Ruby Question

Ruby n.times issue

In use Ruby 2.3, irb

a, b = [], [1,2,3]
3.times do
b[0] += 1
a << b
end


expected:

=> [[2, 2, 3], [3, 2, 3], [4, 2, 3]]


but I get

=> [[4, 2, 3], [4, 2, 3], [4, 2, 3]]


why? Thanks

P.S.

if I do

a = []
3.times do |n|
a << n
end


I get right result
a == [0,1,2]

Answer

You get the same because b is the same object which you are appending 3 times in a. b remains unchanged. That's why a stores the same values.

p a.map(&:object_id) # => three same object id referencing to b. 

Even if you do a[0][1] = 100, you will see the same value reflected in all positions => [[4, 100, 3], [4, 100, 3], [4, 100, 3]]

You should use Array#dup to save intermediate b values.

a, b = [], [1,2,3]
3.times do
  b[0] += 1
  a << b.dup
end
=> [[2, 2, 3], [3, 2, 3], [4, 2, 3]]

For latter part of you question you might want to read - Ruby - Parameters by reference or by value?