Following code was tested with ruby 1.8.7 and Rails 2.3 .
While developing rails application you have must seen this
1 2Called id for nil, which would mistakenly be 4 — if you really 3wanted the id of nil, use object_id 4
We all know that this message is added by Rails and it is called whiny nil . If you open your config/development.rb file you will see
1# Log error messages when you accidentally call methods on nil. 2config.whiny_nils = true
Simply stated it means that if the application happens to invoke id on a nil object then throw an error. Rails assumes that under no circumstance a developer wants to find id of a nil object. So this must be an error case and Rails throws an exception.
The question I have is why 4. Why Matz chose the id of nil to be 4. This awesome presentation on 'Ruby Internals' has the answer.
In short Matz decided to have all the odd numbers reserved for numerical values. Check this out.
1> irb 2>> 0.id 3(irb):1: warning: Object#id will be deprecated; use Object#object_id 4=> 1 5>> 1.id 6(irb):2: warning: Object#id will be deprecated; use Object#object_id 7=> 3 8>> 2.id 9(irb):3: warning: Object#id will be deprecated; use Object#object_id 10=> 5 11>> 3.id 12(irb):4: warning: Object#id will be deprecated; use Object#object_id 13=> 7
Id 1,3,5 and 7 are taken by 0,1,2 and 3.
Now we are left with the id 0,2,4 and higher values.
1> irb 2> FALSE.id 3(irb):5: warning: Object#id will be deprecated; use Object#object_id 4=> 0 5>> TRUE.id 6(irb):6: warning: Object#id will be deprecated; use Object#object_id 7=> 2
FALSE had the id 0 and TRUE has the id 2.
Now the next available id left is 4 and that is taken by NIL.
1> irb 2>> NIL.id 3(irb):7: warning: Object#id will be deprecated; use Object#object_id 4=> 4
We won't even be discussing this issue once 1.9 comes out where we will have to use object_id and then this won't be an issue.
You can follow more discussion about this article at Hacker news .