10月から日本でもマイナンバー制度が始動しましたが、Rubyの世界でもすべてのオブジェクトに番号が振ってあります。
マイナンバーと比較してみる
桁数
日本のマイナンバーは12桁ですが、Rubyのobject_id
は、Integer
であること以上に特に規定がありません。とはいえ、(そして、演算対象でもないので、実際のクラスを気にする必要も事実上ありません)。Fixnum
がマシンのポインタのサイズを基準に設定されている都合上、その幅を越える数のオブジェクトはマシンとして処理できなさそうなので、Bignum
になることはほぼないとは思います
※取り消し部はコメントで追記
設定と変更
マイナンバーは制度開始時に一斉に設定されて、漏洩などで必要になった場合以外は変更しない、という運用ですが、object_id
はオブジェクトの生成とともに振られ、オブジェクトがガベージコレクションの餌食になるまで(もしくは、Rubyごと終了するまで)変化しません。
利用目的
マイナンバーは利用目的が厳密に定められて、それ以外の理由で収集することが禁じられていますが、object_id
はパブリックメソッドであって、プログラマーが自由に値を利用できます。
通称と正式名称
マイナンバーは制度の愛称で、法的な名称は「個人番号」ですが、object_id
も使いやすくした名前で、何かで上書きした場合のために__id__
というメソッドが別途で用意されています。
object_id
の各種性質
マイナンバーはともかく、object_id
についてさらに調べてみました。
変わるもの、変わらないもの
String
はミュータブルなこともあって、同じ文字列リテラルで生成しても違うobject_id
となります。一方、true
、false
、nil
やシンボルといったものは、後から別に書いても同じobject_id
となります。
奇数と偶数
もちろんobject_id
の具体的な値は知る必要がありませんし、あくまで実装依存に過ぎない話ではありますが、手元にあったCRuby 2.2.2、JRuby 1.7.20、Rubinius 2.5.5の全てで、奇数のobject_id
はFixnum
に振られていました。しかも、「2倍して1足した値」という規則正しいものでした(0.object_id == 1
、1.object_id == 3
)。
これは、整数演算に当たって実際にオブジェクトを生成する手間を省略するために、object_id
自体を簡単に変換して値として使えるようにしてあるという、実装の最適化がなされていることが読み取れます。
なお、CRubyでは4で割って2余るobject_id
にFloat
を当てはめていましたが(メモリアラインメントの加減で、実際に参照したいオブジェクトには4の倍数を使うのが便利だかららしい)、JRubyやRubiniusでは偶数に各種のオブジェクトを入れてありました。
object_id
の利用法
「一意な値」として
オブジェクトが一度生成されればobject_id
は不変なので、識別子として使うことができます。自分自身、プログラム中でキャッシュの識別用にobject_id
を使うようなコードを組んでいます。
間接的な参照として
JRubyでは制約があるようですが、ObjectSpace._id2ref
というメソッドがあって、object_id
からそのIDを持つオブジェクトを取得することができます。ふつうにオブジェクトを参照していればガベージコレクション自体起こりませんが、オブジェクト自体を直接参照せずにobject_id
経由で参照することで、参照先をガベージコレクタに回収させることができます。これを使うことで、Rubyの枠内でウィークリファレンスを実装できるようになります(なお、JRubyではJava自体のウィークリファレンスを利用する形で実装されていました)。