中身を見るだけ
arr[0]
# => [[[...], 1]]
arr[0]
要素が 1 つだけの配列です。したがって[1]
、この配列から外れて nil が返されます。
arr[0][0]
# => [[[...]], 1]
arr[0][0]
一番上の配列の 1 つの要素のみに入り、この要素には 2 つの値が含まれているため[1]
、値が見つかります。
arr[0] << arr
あなたがし、しなかったので、そう動作しますarr[0] = arr
。
そうすることで、 as をarr = [[], 1]; arr[0] << arr
設定せずに、配列自体である arr[0] の要素として追加しました。arr
arr[0]
arr
それ以外のことをしていたら
arr = ["whatever", 1]
# => ["whatever", 1]
arr[0] = arr
# => [[...], 1]
arr[0][1]
# => 1
arr[0][0][1]
編集
質問に戻りますが、なぜ再帰配列になるのですか。arr
の値を渡すのではなくarr[0]
、その参照を渡します。
arr = ["whatever", 1]
# => ["whatever", 1]
arr.object_id
# => 69999412942060
arr[0] = arr
# => [[...], 1]
arr[0].object_id
# => 69999412942060
arr[0].object_id == arr.object_id
# => true
arr
それ以来、そこにウロボロスがありarr[0]
、同じオブジェクトを参照しています。
その値を挿入するだけの場合は、最初に deep_copied する必要があります。
arr = ["whatever", 1]
arr_copy = Marshal.load(Marshal.dump(arr)) # copy the value,
# delete the object reference dependence
arr[0] = arr_copy
puts arr.inspect
# [["whatever", 1], 1] # no infinit recurrence.