# Using Ruby version 2.7.8 -- this code may not work in later versions!
require "objspace"
require "json"
object = Object.new
#=> #<Object:0x00007ff174981a08>
object_internals_json = ObjectSpace.dump(object)
#=> "{\"address\":\"0x7ff174981a08\", \"type\":\"OBJECT\", \"class\":\"0x7ff18d991250\", \"ivars\":0, \"memsize\":40, \"flags\":{\"wb_protected\":true}}\n"
JSON.parse(object_internals_json)["address"]
#=> "0x7ff174981a08"
3条答案
按热度按时间hk8txs481#
inspect
的默认实现调用to_s
的默认实现,它只是直接显示对象的十六进制值,如Object#to_s
文档中所示(单击方法描述以显示源代码)。同时,在
object_id
实现的C源代码中的注解显示,Ruby值和对象ID有不同的“命名空间”,这取决于对象的类型(例如,最低位似乎对于除Fixnum之外的所有都为零)。您可以在Object#object_id
文档中看到这一点(单击以显示源代码)。从这里我们可以看到,在“对象id空间”(由
object_id
返回)中,对象的id从右边的第二位开始(第一位为零),但在“值空间”(由inspect
使用)中,它们从右边的第三位开始(前两位为零)。因此,要将值从“对象id空间”转换到“值空间”,我们可以将object_id
向左移动一位,并获得与inspect
相同的结果:注意:关于
object_id
的细节在当时(2010年)是正确的,但在较新的Ruby版本将object_id
与内存地址解耦之后,就不再正确了。现在的答案是沿着“因为object_id
是按需生成的”。见评论。dly7yett2#
它没有什么不同,它是内存地址的十六进制表示:-)
wvmv3b1j3#
Ruby版本2.7将对象的
object_id
与内存地址本身解耦,因此不能将object_id
转换为内存地址,反之亦然。实际上,对象的实际地址可以改变,而它的object_id
保持不变。也就是说,根据您的Ruby版本,
ObjectSpace
模块可能能够返回对象的内存地址。注意:这个库经常变化,所以你最好只在控制台中使用它。