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が同じになることはありません。
これは私にいくつかの質問を提起します:
object_id
を決定するための既知のスキームはありますか?他は基本的にランダムですか?Andrew Grimmの提案を使用して、他の「低ID」オブジェクトを見つけようとしましたが、次のことがわかりました。
MRIでは、オブジェクトのobject_id
は、経営幹部レベルでオブジェクトを表すVALUE
と同じです。ほとんどの種類のオブジェクトでは、このVALUE
は、実際のオブジェクトデータが格納されるメモリ内の場所へのポインターです。オブジェクト自体のプロパティではなく、システムがメモリを割り当てることを決定した場所にのみ依存するため、これは複数の実行中に明らかに異なります。
ただし、パフォーマンス上の理由から、true
、false
、nil
、およびFixnum
sは特別に処理されます。これらのオブジェクトの場合、実際には、オブジェクトのデータをメモリに持つ構造体はありません。オブジェクトのすべてのデータは、VALUE
自体にエンコードされます。 false
、true
、nil
およびFixnum
i
の値はすでに理解しているので、0
、それぞれ2
、4
、i*2+1
。
これが機能する理由は、MRIが実行されるすべてのシステムで、0
、2
、4
およびi*2+1
がヒープ上のオブジェクトに対して有効なアドレスになることはないためです。オブジェクトデータへのポインタとの重複はありません。
整数_(value * 2) + 1
_と非整数_(x * 2)
_の割り当ては、 ヒルベルトのグランドホテルのパラドックス に類似しており、無限に多くのゲストを無限のホテルに割り当てる方法を説明しています。
IDによるオブジェクトの検索に関しては、ObjectSpace._id2ref(object_id)
があります。実装にObjectSpaceがない場合を除きます。