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

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

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

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

>> a.object_id
=> 36971870

>> a.__id__
=> 36971870

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

Ответы [ 2 ]

49 голосов
/ 12 мая 2010

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

Между тем комментарии в источнике 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"
1 голос
/ 12 мая 2010
0x234255E

=>36971870

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

...