0

次のコードが IRB コンソールで実行された場合:

arr = [[], 1]
arr[0]<<arr

結果は[[[...], 1]]です。

その後、、、arr[0]などarr[0][0]arr[0][0][0]同じ出力を生成します。

任意の量のネストを表示することはできないので、これは理にかなっていますよね?

ただし、arr[0][1]nil を生成します (むしろ1) 何ですか? しかし、arr[0][0][1]印刷し1ます。

arr[0][0][0][1] => nil

それから:

arr[0][0][0][0][1] => 1

何が起こっている?実際に作られる構造とは?この構造の再帰の深さはどれくらいですか? ニルはどこから来るのですか?

4

2 に答える 2

1

中身を見るだけ

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] の要素として追加しました。arrarr[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.
于 2013-06-19T05:10:47.537 に答える