I wanted to process data of PBM image using a double array (an array of arrays). When I thought of the initilization of a double array, the code as below first came to my mind.
ar = Array.new(4, Array.new(0, 4))
It is intended to initialize a double array ar
of 4 x
4 with 0. It seems simple and smart :-). But, I found something
strange with a double array ar
...
$ irb irb(main):001:0> ar = Array.new(4, Array.new(4, 0)) # initialization [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] irb(main):002:0> ar[1][1] = 2 # substitution 2 irb(main):003:0> p ar [[0, 2, 0, 0], [0, 2, 0, 0], [0, 2, 0, 0], [0, 2, 0, 0]] # ?? nil
I thought only ar[1]
was changed by ar[1][1] =
2
, however, other arrays were also changed like ar[1]
.
I couldn't find the reason for a while. But finally, I found the
answer in
Ruby FAQ
2.12. When the array ar
is initialized as above, all of
the elements of ar
point to the same object
(Array.new(4, 0)
). Therefore, the operations to one
element seem to affect all of the elements.
In order to avoid this, the array ar
should be
initialized so that each of the elements of ar
point to
different array. For, example..
$ irb irb(main):001:0> ar = Array.new(4).collect { Array.new(4, 0) } # init [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] irb(main):002:0> ar[1][1] = 2 2 irb(main):003:0> p ar [[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] # seems good nil
But, it is easier to use
mdarray
in some cases. When you access out of the range specified at
initialization, an exception is raised.
Feel free to mail me
Copyright (C) 2000 Masahiro SATO