From: Brian Candler Date: 2004-09-29T03:45:05+09:00 Subject: Re: weird behavior pushing an array onto an array > > In my program, I fill an array, a, with data and push it onto an array b > > which is initially empty. > > You push the same array over and over. You want to push a copy instead. > Use #clone or #dup to get a copy of the Array. Beware that may not be enough by itself, because the array contains strings; even if you dup the array you will still have references to the same strings. This will become apparent if you later modify one of the strings: a = ["one","two","three"] b = [] b << a.dup << a.dup b[0][0] << "XXX" p b # => [["oneXXX", "two", "three"], ["oneXXX", "two", "three"]] But it's not an issue if you only ever replace the array elements with a reference to another object, e.g. b[0][0] = "newstring" A safer way is to fill the array directly: b = [] 5.times do b << ["ACINX", "28.53", "15.63", "3.95", "7.76", "1.05", 0] end Or more compactly, b = (1..5).collect { ["ACINX", "28.53", "15.63", "3.95", "7.76", "1.05", 0] } That's because each time a constant like "ACINX" is executed, it creates a brand new String object; equally, each time [ ... ] is executed it creates a brand new Array object. Alternatively, you can do a "deep copy" of the array and its contents. A quick and fairly convenient way to do this is with Marshal, to serialise the object and then create a fresh object tree from the serialised form. a = ["one","two","three"] b = [] b << Marshal.load(Marshal.dump(a)) << Marshal.load(Marshal.dump(a)) b[0][0] << "XXX" p b # => [["oneXXX", "two", "three"], ["one", "two", "three"]] Regards, Brian.