I'm playing around with Ruby's .object_id
and noticed that, in several sequential sessions of irb, I get these identical results:
我正在摆弄Ruby的.object_id,并注意到,在irb的几个连续会话中,我得到了这些相同的结果:
false.object_id // 0
true.object_id // 2
nil.object_id // 4
100.object_id // 201
In fact, every integer's object_id seems to be ((value * 2) + 1).
事实上,每个整数的object_id似乎都是((值* 2)+ 1)。
On the other hand, a given string's object_id is never the same after exiting and re-running irb.
另一方面,给定的字符串的object_id在退出和重新运行irb之后永远不会相同。
This raises several questions for me:
这给我带来了几个问题:
- Is there a known scheme by which certain
object_id
s are determined? Are others basically random? - 是否有确定某些object_id的已知方案?其他人基本上是随机的吗?
- The ids for true, false, and nil, aren't sequential. Is there a way to ask what object is represented by a given id? (I'm curious what the other single-digit and ids are tied to.)
- true、false和nil的id不是顺序的。有没有一种方法可以问给定id表示什么对象?(我很好奇其他的个位数和id是什么关系。)
- Could you (not that you should) write obfuscated Ruby where you use known object ids to refer to objects without naming them, like "object of id 201 + object of id 19" to mean "100 + 9"?
- 你能(不是说你应该)写一个模糊的Ruby吗?在这里你使用已知的对象id来引用对象而不命名它们,比如“id 201 + id 19的对象”来表示“100 + 9”。
Update
Using Andrew Grimm's suggestion, I tried discovering other "low id" objects, but found that:
使用Andrew Grimm的建议,我尝试去发现其他“低id”对象,但是发现:
- There don't appear to be any more even-numbered objects in this sequence - ids 6, 8, 10, etc don't point to anything.
- 在这个序列中似乎没有更多偶数编号的对象——id 6、8、10等等没有指向任何东西。
- As implied by my earlier experiment, all the odd-numbered ids belong to numbers. Specifically, id 1 points to the number 0, 3 points to 1, 5 points to 2, and so forth.
- 正如我之前的实验所暗示的,所有奇数id都属于数字。具体地说,id 1指向数字0,3指向1,5指向2,以此类推。
2 个解决方案
#1
61
In MRI the object_id
of an object is the same as the VALUE
that represents the object on the C level. For most kinds of objects this VALUE
is a pointer to a location in memory where the actual object data is stored. Obviously this will be different during multiple runs because it only depends on where the system decided to allocate the memory, not on any property of the object itself.
在MRI中,对象的object_id与表示C级对象的值相同。对于大多数类型的对象,这个值是指向存储实际对象数据的内存中的位置的指针。显然,这在多次运行时是不同的,因为它只取决于系统决定分配内存的位置,而不取决于对象本身的任何属性。
However for performance reasons true
, false
, nil
and Fixnum
s are handled specially. For these objects there isn't actually a struct with the object's data in memory. All of the object's data is encoded in the VALUE
itself. As you already figured out the values for false
, true
, nil
and any Fixnum
i
, are 0
, 2
, 4
and i*2+1
respectively.
但是由于性能原因,true、false、nil和Fixnums都被特别处理。对于这些对象,实际上并没有在内存中包含对象数据的结构体。对象的所有数据都编码在值本身中。正如您已经计算出false、true、nil和任何Fixnum i的值,分别是0,2,4和i*2+1。
The reason that this works is that on any systems that MRI runs on, 0
, 2
, 4
and i*2+1
are never valid addresses for an object on the heap, so there's no overlap with pointers to object data.
这样做的原因是,在任何MRI运行的系统上,0,2,4和i*2+1都不是堆上对象的有效地址,因此不会与指向对象数据的指针重叠。
#2
29
Assigning Integer (value * 2) + 1
and non-integers (x * 2)
is analogous to Hilbert's paradox of the Grand Hotel, which describes how to assign infinitely more guests to an infinite hotel.
赋值整数(值* 2)+ 1和非整数(x * 2)类似于希尔伯特的大旅馆悖论,它描述了如何将无限多的客人分配给无限的旅馆。
With regards to finding objects by their ID, there's ObjectSpace._id2ref(object_id)
. Unless your implementation doesn't have ObjectSpace.
关于通过它们的ID查找对象,有ObjectSpace._id2ref(object_id)。除非你的实现没有ObjectSpace。
#1
61
In MRI the object_id
of an object is the same as the VALUE
that represents the object on the C level. For most kinds of objects this VALUE
is a pointer to a location in memory where the actual object data is stored. Obviously this will be different during multiple runs because it only depends on where the system decided to allocate the memory, not on any property of the object itself.
在MRI中,对象的object_id与表示C级对象的值相同。对于大多数类型的对象,这个值是指向存储实际对象数据的内存中的位置的指针。显然,这在多次运行时是不同的,因为它只取决于系统决定分配内存的位置,而不取决于对象本身的任何属性。
However for performance reasons true
, false
, nil
and Fixnum
s are handled specially. For these objects there isn't actually a struct with the object's data in memory. All of the object's data is encoded in the VALUE
itself. As you already figured out the values for false
, true
, nil
and any Fixnum
i
, are 0
, 2
, 4
and i*2+1
respectively.
但是由于性能原因,true、false、nil和Fixnums都被特别处理。对于这些对象,实际上并没有在内存中包含对象数据的结构体。对象的所有数据都编码在值本身中。正如您已经计算出false、true、nil和任何Fixnum i的值,分别是0,2,4和i*2+1。
The reason that this works is that on any systems that MRI runs on, 0
, 2
, 4
and i*2+1
are never valid addresses for an object on the heap, so there's no overlap with pointers to object data.
这样做的原因是,在任何MRI运行的系统上,0,2,4和i*2+1都不是堆上对象的有效地址,因此不会与指向对象数据的指针重叠。
#2
29
Assigning Integer (value * 2) + 1
and non-integers (x * 2)
is analogous to Hilbert's paradox of the Grand Hotel, which describes how to assign infinitely more guests to an infinite hotel.
赋值整数(值* 2)+ 1和非整数(x * 2)类似于希尔伯特的大旅馆悖论,它描述了如何将无限多的客人分配给无限的旅馆。
With regards to finding objects by their ID, there's ObjectSpace._id2ref(object_id)
. Unless your implementation doesn't have ObjectSpace.
关于通过它们的ID查找对象,有ObjectSpace._id2ref(object_id)。除非你的实现没有ObjectSpace。