Подтвердить что ты не робот

В Ruby почему index() печатает какой-то идентификатор объекта, который отличается от того, что 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"
4b9b3361

Ответ 1

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

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

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

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

> a = Foo.new
=> #<Foo:0x5cfe4>
> '%x' % (a.object_id << 1)
=> "5cfe4"

Ответ 2

0x234255E

=>36971870

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