空の配列をつくるときに自分が何度も同じ間違いをしていたのでメモしておく。
結論
Array.new(2, [])
上のような書き方はやめたほうがよく
Array.new(2) { [] }
ブロックを渡して書いたほうがいい。
理由
なぜならArray.new(2, [])
と書くと、全ての要素が同じ配列を参照してしまうから。
具体例
arr = Array.new(2, [])
p arr
arr[0] << "abc"
p arr
先頭の配列arr[0]
に"abc"を追加したのに、arr[1]
にも追加されている。
$ ruby sample.rb
[[], []]
[["abc"], ["abc"]]
ブロックで渡すと、それぞれの要素が独立した配列を参照するようになる。
arr = Array.new(2) { [] }
p arr
arr[0] << "abc"
p arr
この場合はarr[0]
のみが変更され、arr[1]
は変わらない。
$ ruby sample.rb
[[], []]
[["abc"], []]
代入した場合は、参照元が変わるので、他の要素に影響しない。
arr = Array.new(2, [])
p arr
arr[0] = "abc"
p arr
先頭の要素arr[0]
だけが変更され、先頭の要素arr[1]
は空の配列のまま。
$ ruby sample.rb
[[], []]
["abc", []]
まとめ
空の二次元配列をつくるときはArray.new(2) { [] }
とブロックを渡すようにする。