Live data from Hacker News

Ask Matz: why the id of nil is 4?

blog.bigbinary.com

11–19 of 19 posts

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

#11
You may find Gudeman's "Representing Type Information in Dynamically Typed Languages" (http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.39.43...) interesting - it's an overview of type tagging strategies used in many dynamically typed languages. It's not specific to Ruby (it's from 1993), but gives more context to the methods Ruby uses.

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

#12

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.

Oops! Indeed

  (7  15

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

#13

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.

Since in Ruby false and nil are the only "falsish" values and everything else is true, their values has been chosen to make a boolean test as efficient as possible. See: https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#...

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

#14

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…

wow I didn't know you can multi-line highlight code like that in GitHub. Thanks for the tip!

(click on the second github link and you'll note multiple lines are highlighted. check the url for how it's done)

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

#16

Earlier quoted context omitted.

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

Oops! Indeed (7 15

Might also want to use 'last' instead of 'first' in this part of your explantion

> tag the first bit w/ 1

I was confused with your explanation until I went and redid the binary on the original, then I got what you meant. sorry if its nitpicky. ignore if you got it.

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

#17
Hm, I think it's better style to refer to true and false as true and false (their keywords) instead of TRUE and FALSE (constants, could go away in the future?). :)

  irb(main):001:0» TRUE
  » true
  irb(main):002:0» FALSE
  » false

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

#18

Earlier quoted context omitted.

Oops! Indeed (7 15

Might also want to use 'last' instead of 'first' in this part of your explantion > tag the first bit w/ 1 I was confused with your explanation until I went and redid the binary on the original, then I got what you meant. sorry if its nitpicky. ignore if you got it.

http://en.wikipedia.org/wiki/Bit_numbering

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

#19
post #6

Earlier quoted context omitted.

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.

Ah, that was a mistake. ActiveRecord should have avoided :id until it was renamed in core Ruby, or returned some sentinel (other than nil) whose :id method fails. Assuming Ruby didn't critically depend on :id succeeding for every object, that is.
Post reply on HN