LoginSignup
5
4

More than 5 years have passed since last update.

オブジェクトのマイナンバー〜Rubyのobject_idを調べてみた

Last updated at Posted at 2015-10-30

10月から日本でもマイナンバー制度が始動しましたが、Rubyの世界でもすべてのオブジェクトに番号が振ってあります。

マイナンバーと比較してみる

桁数

日本のマイナンバーは12桁ですが、Rubyのobject_idは、Integerであること以上に特に規定がありません。とはいえ、Fixnumがマシンのポインタのサイズを基準に設定されている都合上、その幅を越える数のオブジェクトはマシンとして処理できなさそうなので、Bignumになることはほぼないとは思います(そして、演算対象でもないので、実際のクラスを気にする必要も事実上ありません)。

※取り消し部はコメントで追記

設定と変更

マイナンバーは制度開始時に一斉に設定されて、漏洩などで必要になった場合以外は変更しない、という運用ですが、object_idはオブジェクトの生成とともに振られ、オブジェクトがガベージコレクションの餌食になるまで(もしくは、Rubyごと終了するまで)変化しません。

利用目的

マイナンバーは利用目的が厳密に定められて、それ以外の理由で収集することが禁じられていますが、object_idはパブリックメソッドであって、プログラマーが自由に値を利用できます。

通称と正式名称

マイナンバーは制度の愛称で、法的な名称は「個人番号」ですが、object_idも使いやすくした名前で、何かで上書きした場合のために__id__というメソッドが別途で用意されています。

object_idの各種性質

マイナンバーはともかく、object_idについてさらに調べてみました。

変わるもの、変わらないもの

Stringはミュータブルなこともあって、同じ文字列リテラルで生成しても違うobject_idとなります。一方、truefalsenilやシンボルといったものは、後から別に書いても同じobject_idとなります。

奇数と偶数

もちろんobject_idの具体的な値は知る必要がありませんし、あくまで実装依存に過ぎない話ではありますが、手元にあったCRuby 2.2.2、JRuby 1.7.20、Rubinius 2.5.5の全てで、奇数のobject_idFixnumに振られていました。しかも、「2倍して1足した値」という規則正しいものでした(0.object_id == 11.object_id == 3)。

これは、整数演算に当たって実際にオブジェクトを生成する手間を省略するために、object_id自体を簡単に変換して値として使えるようにしてあるという、実装の最適化がなされていることが読み取れます。

なお、CRubyでは4で割って2余るobject_idFloatを当てはめていましたが(メモリアラインメントの加減で、実際に参照したいオブジェクトには4の倍数を使うのが便利だかららしい)、JRubyやRubiniusでは偶数に各種のオブジェクトを入れてありました。

object_idの利用法

「一意な値」として

オブジェクトが一度生成されればobject_idは不変なので、識別子として使うことができます。自分自身、プログラム中でキャッシュの識別用にobject_idを使うようなコードを組んでいます。

間接的な参照として

JRubyでは制約があるようですが、ObjectSpace._id2refというメソッドがあって、object_idからそのIDを持つオブジェクトを取得することができます。ふつうにオブジェクトを参照していればガベージコレクション自体起こりませんが、オブジェクト自体を直接参照せずにobject_id経由で参照することで、参照先をガベージコレクタに回収させることができます。これを使うことで、Rubyの枠内でウィークリファレンスを実装できるようになります(なお、JRubyではJava自体のウィークリファレンスを利用する形で実装されていました)。

5
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4