Почему в Ruby inspect() выводит какой-то идентификатор объекта, который отличается от того, что дает object_id()?

Когда функция p используется для распечатки объекта, она может дать идентификатор, который отличается от того, что дает object_id(). В чем причина разных цифр?

Обновление: 0x4684abc отличается от 36971870, то есть 0x234255E.

>> a = Point.new
=> #<Point:0x4684abc>

>> a.object_id
=> 36971870

>> a.__id__
=> 36971870

>> "%X" % a.object_id
=> "234255E"

person nonopolarity    schedule 12.05.2010    source источник


Ответы (2)


Реализация по умолчанию inspect вызывает реализацию по умолчанию to_s, которая просто показывает непосредственно шестнадцатеричное значение объекта, как показано в методе Object#to_s docs (нажмите на описание метода, чтобы открыть источник).

Между тем комментарии в исходном коде C, лежащие в основе реализации object_id, показывают, что существуют разные «пространства имен» для значений Ruby и идентификаторов объектов, в зависимости от типа объекта (например, младший бит кажется равным нулю для всех, кроме Fixnums). Вы можете увидеть это в Object#object_id документах (нажмите, чтобы открыть источник ).

Отсюда мы можем видеть, что в «пространстве идентификаторов объектов» (возвращенном object_id) идентификаторы объектов начинаются со второго бита справа (с первым битом, равным нулю), но в «пространстве значений» (используется inspect) они начинаются с третьего бита справа (с первыми двумя нулевыми битами). Итак, чтобы преобразовать значения из «пространства идентификаторов объектов» в «пространство значений», мы можем сдвинуть object_id влево на один бит и получить тот же результат, что и inspect:

> '%x' % (36971870 << 1)
=> "4684abc"

> a = Foo.new
=> #<Foo:0x5cfe4>
> '%x' % (a.object_id << 1)
=> "5cfe4"
person Arkku    schedule 12.05.2010
comment
эти ссылки на ruby-doc.org уже мертвы :-( - person AlexChaffee; 10.10.2011
comment
@AlexChaffee Я больше не мог найти прямые ссылки на источники методов, отредактировал сообщение с косвенными ссылками. - person Arkku; 11.10.2011

0x234255E

=>36971870

Это не другое, это шестнадцатеричное представление адреса памяти :-)

person Robbie    schedule 12.05.2010
comment
0x4684abc = 2 * 0x234255E, но почему? )) - person andrykonchin; 12.05.2010
comment
@aaz: Потому что object_id сдвигает адрес объекта влево на один бит (что эквивалентно умножению на два). Смотрите мой ответ для ссылки на источник. - person Arkku; 12.05.2010