views:

130

answers:

2

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"
+1  A: 
0x234255E

=>36971870

It's not different, it's the hexadecimal representation of the memory address:-)

Robbie
And the `4684abc`?
Jeriko
yes it was meant to compare 0x4684abc and 36971870
動靜能量
0x4684abc = 2 * 0x234255E, but why? ))
aaz
@aaz: Because `object_id` shifts the object's address to the left by one bit (which is the same as multiplying by two). See my answer for link to source.
Arkku
+4  A: 

The default implementation of inspect calls the default implementation of to_s, which just shows the hexadecimal value of the object directly, as seen here: http://ruby-doc.org/core/classes/Object.src/M000359.html

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): http://ruby-doc.org/core/classes/Object.src/M000339.html

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 by inspect) 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 the object_id to the left by one bit and get the same result that is shown by inspect:

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

> a = Foo.new
=> #<Foo:0x5cfe4>
> '%x' % (a.object_id << 1)
=> "5cfe4"
Arkku
haha, do you write compilers for fun during leisure time?
動靜能量