在Ruby中,为什么inspect()打印出某种与object_id()给出的不同的对象id?
当p
函数用于打印对象时,它可能会给出一个ID,它与object_id()
给出的不同。数字不同的原因是什么?
更新: 0x4684abc
与 36971870
不同,即 0x234255E
>> a = Point.new
=> #<Point:0x4684abc>
>> a.object_id
=> 36971870
>> a.__id__
=> 36971870
>> "%X" % a.object_id
=> "234255E"
When the p
function is used to print out an object, it may give an ID, and it is different from what object_id()
gives. What is the reason for the different numbers?
Update: 0x4684abc
is different from 36971870
, which is 0x234255E
>> a = Point.new
=> #<Point:0x4684abc>
>> a.object_id
=> 36971870
>> a.__id__
=> 36971870
>> "%X" % a.object_id
=> "234255E"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
inspect
的默认实现调用了to_s
的默认实现,它只是直接显示对象的十六进制值,如Object#to_s
中所示> docs(点击方法描述即可显示源代码)。同时,
object_id
实现的 C 源代码中的注释表明,根据对象的类型,Ruby 值和对象 id 有不同的“命名空间”(例如,最低位似乎为零对于除 Fixnums 之外的所有对象)。您可以在Object#object_id
docs 中看到这一点(点击即可显示来源)。从那里我们可以看到,在“object id space”(由
object_id
返回)中,对象的 id 从右侧第二位开始(第一位为零),但在“value space”(由inspect
使用),它们从右侧的第三位开始(前两位为零)。因此,要将值从“对象 id 空间”转换为“值空间”,我们可以将object_id
向左移动一位,并得到与显示的相同结果检查
:注意:有关
object_id
的详细信息在当时(2010年)是正确的,但在新的Ruby版本解耦object_id之后就不再正确了
来自内存地址。现在答案更接近“因为object_id
是按需生成的”。见评论。The default implementation of
inspect
calls the default implementation ofto_s
, which just shows the hexadecimal value of the object directly, as seen in theObject#to_s
docs (click on the method description to reveal the source).Meanwhile the comments in the C source underlying the implementation of
object_id
shows that there are different “namespaces” for Ruby values and object ids, depending on the type of the object (e.g. the lowest bit seems to be zero for all but Fixnums). You can see that inObject#object_id
docs (click to reveal the source).From there we can see that in the “object id space” (returned by
object_id
) the ids of objects start from the second bit on the right (with the first bit being zero), but in “value space” (used byinspect
) they start from the third bit on the right (with the first two bits zero). So, to convert the values from the “object id space” to the “value space”, we can shift theobject_id
to the left by one bit and get the same result that is shown byinspect
:Note: The details about
object_id
were correct at the time (2010), but aren't anymore after newer Ruby versions have decoupledobject_id
from memory addresses. Now the answer is more along the lines "becauseobject_id
is generated on demand". See comments.没有什么不同,都是内存地址的十六进制表示:-)
It's not different, it's the hexadecimal representation of the memory address:-)
Ruby 2.7 版本将对象的
object_id
与内存地址本身解耦,因此您无法将object_id
转换为内存地址,反之亦然。事实上,对象的实际地址可以更改,而其object_id
保持不变。也就是说,根据您的 Ruby 版本,
ObjectSpace
模块可能能够返回对象的内存地址。注意:该库经常更改,因此很可能您应该只在控制台中使用它。Ruby version 2.7 decoupled the object's
object_id
from the memory address itself, so you can't transform anobject_id
into a memory address or vice versa. In fact, the object's actual address can change while itsobject_id
remains the same.That said, depending on your Ruby version, the
ObjectSpace
module might be able to return an object's memory address. Note: this library changes frequently, so most likely you should only use it in the console.