Накратко
целите числа са вероятно най-често използваният "вид" обекти в повечето програми.
Такива детайли са специфични за имплементацията, така че тук се има предвид главно MRI(референтната имплементация, която почти всички ползваме)
В този смисъл, интернирането им спестява
- памет (не се създава отделна C структура за всяко число)
- време (спестяват се проследявания на pointer-и, защото стойността се взима директно)
Имплементационни детайли и C магия
Начинът, по който това работи в MRI е сравнително прост.
Най-общо казано, на всеки Ruby обект съответства стойност от C типа VALUE.
Най-елементарното решение в една имплементация би било тази стойност да е просто pointer към C структура, съдържаща данните на обекта. В MRI това е почти така, но не и за няколко специални типа стойности.
VALUE e дефинирано като typedef uintptr_t VALUE, тоест неотрицателно цяло число, което е със size, достатъчен за да съдържа адреса на pointer. Това число е точно #object_id на един обект в Руби, така че лесно може да се поиграе и да се разгледа в irb.
Всеки път, когато MRI се опита да интерпретира VALUE стойност, то проверява вътрешния и интерпретатор-специфичен клас, който е закодиран чрез определени битове в това число. Специфично, Fixnum обектите са точно тези, чиито последен бит е 1. Когато такъв обект бъде засечен, още един бит кодира знака, и останалите 30 на 32-битова / 62 на 64-битова архитектура съдържат директно стойността на числото.
Именно затова всяко x с клас Fixnum x.object_id == 2 * x + 1
По подобен начин се интернират true, false, nil и символите. За сравнение, при обикновените обекти, VALUE се използва като адрес на структура с полета, методи и т.н. Пример:
struct RClass {
struct RBasic basic;
VALUE super;
rb_classext_t *ptr;
struct method_table_wrapper *m_tbl_wrapper;
};