Be careful with your Array initializers

Posted by admin, Thu Aug 23 07:59:28 UTC 2007

This one had me going for couple of hours today. I wanted to segregate some data into “buckets”. So I initialized my array of arrays (buckets), and then proceeded to add stuff to the individual buckets. But my unit test was failing, because, for a system of 10 buckets, and me adding 1 thing, I always got back 10 things. Weird. But look at this:

$ irb irb(main):001:0> foo = Array.new(10, []) => [[], [], [], [], [], [], [], [], [], []] irb(main):003:0> foo[0] << 1 => [1] irb(main):004:0> foo => [[1], [1], [1], [1], [1], [1], [1], [1], [1], [1]] irb(main):005:0>

WTF? So, that array that I initialized my buckets with? The same array. Add to one, add to all. Grrr.

Now, I know this is in the PickAxe book, in the RDocs for Array.new… But I never read that far, ok?

So, for the confused, the correct answer is to use a block initializer like so: irb(main):008:0> foo = Array.new(10) { [] } => [[], [], [], [], [], [], [], [], [], []] irb(main):009:0> foo[0] << 1 => [1] irb(main):010:0> foo => [[1], [], [], [], [], [], [], [], [], []] irb(main):011:0>

Filed Under: | Tags:

Comments

Have your say

A name is required. You may use HTML in your comments.