VALUE: special const
Ruby から見えるすべてはオブジェクトである、という言説がある。実際、数値など 1 + 2
は 1.+(2)
といったように、オブジェクトとメソッドの組み合わせで表現される。
オブジェクトをどのように表現するかは、処理系のデザインとしては難しい問題だ。一番ナイーブに作るには、オブジェクトを作成すると、すべてメモリを割り当てる、という手法が考えられる。実際、Array オブジェクトを生成すると、(GC 管理の)メモリを割り当てる。このとき、割り当てた配列オブジェクトへのポインタが VALUE
の値である。すなわち、Array オブジェクトの場合、VALUE
はポインタということになる。
ただ、数値、とくに整数値などはよく使うので、毎回割り当てるのはオーバヘッド的に大変だ。例えば、n.times{|i| ...}
とすると、0~n までの整数が登場するが、毎回それを割り当てるのは大変そうだ。また、よく使う nil
なんかも、毎回割り当てるのは変な気がする。そもそも、nil
オブジェクトは1個だから、なんか特別なモノでも良い気がする。
VALUE
は 32bit ないし 64bit の非負整数値である。ここに、いろいろな形でエンコーディングすることで、いくつかの種類のオブジェクトを表現している。
- Fixnum (ある上限・下限をもつ整数値, 2.5 以降は Integer として独立しているが、処理系内部では異なる扱いをしている)
- Flonum(ある上限・下限、精度の制限をもつ浮動小数点数。Ruby からは Float として、Flonum もそうじゃないものも、透過的に見えるが、処理系内部では異なる扱いをしている)
- Symbol(static symbol と呼ばれるもの)
- 特殊な即値
true
false
nil
undef
(Ruby レベルからは観測できない、処理系内で使う特殊な値)
- メモリへのポインタ(上記以外のオブジェクト)
ポインタ以外を、ソースコード中では special const(特殊定数)と呼んでおり(多分)、SPECIAL_CONST_P(v)
で special const かどうかを判断している。適当な名前だなあ。