The Secret of Object#to_s
There’s something about Ruby that I’ve wanted to know for a long time: where does the hexadecimal value in #<Object:0x000001009e60f8>
come from? Today I finally went looking for the answer.
When in doubt, look at the code
The documentation for Object#to_s
tells us that the value is based on the object id: “Returns a string representing obj. The default to_s
prints the object‘s class and an encoding of the object id.”
Looking at the source code for to_s
, we can see that it’s using sprintf
to create the hexadecimal value. From object.c
:
You can find this code in the Ruby source code in the file ruby-VERSION/object.c
Now, Ruby’s sprintf doesn’t support %p
or %lx
but it does support %x
. However, there’s obviously more to the story because the values still don’t match up:
So what do we need to do to the object id to get the real hexadecimal value?
A tiny calculation
If we take a look at the hexadecimal values in plain-old decimal, the answer becomes obvious. Can you see it?
All we have to do is double it!
And the answer is…
Note: I’ve created a tiny project called Hexoid to handle the minor formatting difference between Ruby 1.8 and 1.9.