Live data from Hacker News

Ask Matz: why the id of nil is 4?

blog.bigbinary.com

1–10 of 19 posts

Re: Ask Matz: why the id of nil is 4?

#4

Much less relevant today with Ruby 1.9.x, but still very interesting.

Less relevant how? nil.object_id is still 4 in MRI 1.9.2.

The article noted that all integers have odd ids, but not why—the LSB is a http://c2.com/cgi/wiki?TagBit in MRI. I would hope other implementations are permitted to choose different schemes; it would suck if user code began assuming nobody found a use for more than one tag bit.

Re: Ask Matz: why the id of nil is 4?

#6

Much less relevant today with Ruby 1.9.x, but still very interesting.

Less relevant how? nil.object_id is still 4 in MRI 1.9.2. The article noted that all integers have odd ids, but not why—the LSB is a http://c2.com/cgi/wiki?TagBit in MRI. I would hope other implementations are permitted to choose different schemes; it would suck if user code began assuming nobody found a use for more than one tag bit.

This situation was most encountered by Rails developers trying to access the ID of an ActiveRecord object. Since they changed the method to object_id in Ruby 1.9, calling id on a nil object should just give a NoMethodError instead of that slightly cryptic warning.

Re: Ask Matz: why the id of nil is 4?

#7
Fixnum values (numbers smaller than native one machine word minus 1 bit) are stored in an object pointer. When you do object.id it returns the address stored in that pointer.

For Ruby to know that the value in a pointer is a Fixnum (and not a pointer to an address), it will tag the first bit w/ 1 and shift the integer value by one bit. So storing the value 7 will be done like this:

  (7  14
This is why 7.id == 14.

You can see where this is implemented right here: https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#...

For true, false and nil they are also stored right in the object pointer using special values defined here: https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#.... You'll notice that those 3 values in binary format all end with 0b...10. First bit to 1 means Fixnum, second bit to 1 means special value: true, false or nil.

Re: Ask Matz: why the id of nil is 4?

#9

Fixnum values (numbers smaller than native one machine word minus 1 bit) are stored in an object pointer. When you do object.id it returns the address stored in that pointer. For Ruby to know that the value in a pointer is a Fixnum (and not a pointer to an address), it will tag the first bit w/ 1 and shift the integer value by one bit. So storing the value 7 will be done like this: (7 14 This is why 7.id == 14. You c…

I found it very odd that he would place false before true, but then I realized that's probably just the C mindset leaking through.

Re: Ask Matz: why the id of nil is 4?

#10

Fixnum values (numbers smaller than native one machine word minus 1 bit) are stored in an object pointer. When you do object.id it returns the address stored in that pointer. For Ruby to know that the value in a pointer is a Fixnum (and not a pointer to an address), it will tag the first bit w/ 1 and shift the integer value by one bit. So storing the value 7 will be done like this: (7 14 This is why 7.id == 14. You c…

Sorry for nitpicking, but you meant 15, not 14. Other than that, it seems you are 100% right.
Post reply on HN