Use this instead:
a = Array.new(3){ [] }
With your code the same object is used for the value of each entry; once you mutate one of the references you see all others change. With the above you instead invoke the block each time a new value is needed, which returns a new array each time.
This is similar in nature to the new user question about why the following does not work as expected:
str.gsub /(<([a-z]+)>/, "-->#{$1}<--"
In the above, string interpolation occurs before the gsub
method is ever called, so it cannot use the then-current value of $1
in your string. Similarly, in your question you create an object and pass it to Array.new
before Ruby starts creating array slots. Yes, the runtime could call dup
on the item by default…but that would be potentially disastrous and slow. Hence you get the block form to determine on your own how to create the initial values.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…