48

私はRubyで遊んでいて.object_id、irbのいくつかの連続したセッションで、これらの同じ結果が得られることに気づきました。

false.object_id // 0
true.object_id // 2
nil.object_id // 4
100.object_id // 201

実際、すべての整数のobject_idは((value * 2)+ 1)のようです。

一方、irbを終了して再実行した後は、特定の文字列のobject_idが同じになることはありません。

これは私にいくつかの質問を提起します:

  1. 特定のを決定するための既知のスキームはありobject_idますか?他は基本的にランダムですか?
  2. true、false、およびnilのIDはシーケンシャルではありません。特定のIDでどのオブジェクトが表されているかを確認する方法はありますか?(他の1桁とIDが何に関連付けられているのか知りたいです。)
  3. 「100+9」を意味する「ID201のオブジェクト+ID19のオブジェクト」のように、既知のオブジェクトIDを使用してオブジェクトに名前を付けずに参照する難読化されたRubyを記述できますか(そうすべきではありません)。

アップデート

Andrew Grimmの提案を使用して、他の「低ID」オブジェクトを見つけようとしましたが、次のことがわかりました。

  • このシーケンスにはこれ以上偶数のオブジェクトはないようです。ID6、8、10などは何も指していません。
  • 私の以前の実験で示唆されたように、すべての奇数番号のIDは番号に属しています。具体的には、id 1は0を指し、3は1を指し、5は2を指します。
4

2 に答える 2

66

MRI では、オブジェクトの はC レベルのオブジェクトを表すobject_idと同じです。VALUEほとんどの種類のオブジェクトでは、これVALUEは実際のオブジェクト データが格納されているメモリ内の場所へのポインタです。オブジェクト自体のプロパティではなく、システムがメモリの割り当てを決定した場所にのみ依存するため、複数回の実行では明らかに異なります。

ただし、パフォーマンス上の理由からtruefalse、 、nilおよびFixnumは特別に処理されます。これらのオブジェクトの場合、メモリ内にオブジェクトのデータを含む構造体は実際にはありません。オブジェクトのすべてのデータは、VALUEそれ自体でエンコードされます。falsetruenilおよび anyの値は、Fixnum iそれぞれ024およびi*2+1です。

これが機能する理由は、MRI が実行されるシステムでは、024およびi*2+1がヒープ上のオブジェクトの有効なアドレスではないため、オブジェクト データへのポインターと重複しないためです。

于 2010-08-07T12:47:44.743 に答える
34

整数(value * 2) + 1と非整数の割り当ては、無限のホテルに無限に多くのゲストを割り当てる方法を説明するヒルベルトのグランド ホテルのパラドックスに(x * 2)類似しています。

ID によるオブジェクトの検索に関しては、ObjectSpace._id2ref(object_id). 実装に ObjectSpace がない場合を除きます。

于 2010-08-07T12:01:47.860 に答える