signo - ruby puts hash
En Ruby, ¿por qué inspect() imprime algún tipo de id de objeto que es diferente de lo que object_id() da? (2)
La implementación predeterminada de inspect
llama a la implementación predeterminada de to_s
, que solo muestra el valor hexadecimal del objeto directamente, como se ve en Object#to_s
docs (haga clic en la descripción del método para revelar la fuente).
Mientras tanto, los comentarios en la fuente C que subyace a la implementación de object_id
muestran que hay diferentes "espacios de nombres" para los valores de Ruby y los identificadores de objetos, dependiendo del tipo del objeto (por ejemplo, el bit más bajo parece cero para todos menos Fixnums). Puede ver eso en Object#object_id
docs (haga clic para ver la fuente).
Desde allí podemos ver que en el "espacio de id del objeto" (devuelto por object_id
) los identificadores de objetos comienzan desde el segundo bit a la derecha (con el primer bit siendo cero), pero en "espacio de valor" (utilizado por inspect
) comienzan desde el tercer bit a la derecha (con los primeros dos bits cero). Entonces, para convertir los valores del "espacio de id del objeto" al "espacio de valor", podemos desplazar el object_id
a la izquierda en un bit y obtener el mismo resultado que se muestra al inspect
:
> ''%x'' % (36971870 << 1)
=> "4684abc"
> a = Foo.new
=> #<Foo:0x5cfe4>
> ''%x'' % (a.object_id << 1)
=> "5cfe4"
Cuando la función p
se utiliza para imprimir un objeto, puede dar una ID, y es diferente de lo que da object_id()
. ¿Cuál es el motivo de los diferentes números?
Actualización: 0x4684abc
es diferente de 36971870
, que es 0x234255E
>> a = Point.new
=> #<Point:0x4684abc>
>> a.object_id
=> 36971870
>> a.__id__
=> 36971870
>> "%X" % a.object_id
=> "234255E"
0x234255E
=>36971870
No es diferente, es la representación hexadecimal de la dirección de memoria :-)