nelmoの日記帳

エンジニア見習いの備忘録とかです。

Array#newする時の初期値は同一オブジェクトになる

本日のRubyに関する学び。

[32] pry(main)> arr = Array.new(3, Array.new(4,0))
[
    [0] [
        [0] 0,
        [1] 0,
        [2] 0,
        [3] 0
    ],
    [1] [
        [0] 0,
        [1] 0,
        [2] 0,
        [3] 0
    ],
    [2] [
        [0] 0,
        [1] 0,
        [2] 0,
        [3] 0
    ]
]
[33] pry(main)> arr[0][0] = 1
1
[34] pry(main)> arr
[
    [0] [
        [0] 1, #<= ここが1になるが、
        [1] 0,
        [2] 0,
        [3] 0
    ],
    [1] [
        [0] 1, #<= ここと
        [1] 0,
        [2] 0,
        [3] 0
    ],
    [2] [
        [0] 1, #<= ここも1になる。
        [1] 0,
        [2] 0,
        [3] 0
    ]
]

Array.newする時に第二引数で配列の要素を埋める初期値を指定することができるが、ここで指定したobjectは全て同一のオブジェクトになる。今回の例では、Array.newされた単一のArrayが3つの要素に埋められる。そのため、一つの要素を変更するとその他の要素にも変更が及んでしまう。

[35] pry(main)> arr[0].object_id
70212079356840
[36] pry(main)> arr[1].object_id
70212079356840
[37] pry(main)> arr[0].object_id.eql?(arr[1].object_id)
true

訳あって多次元配列を作っていたらハマったので。