Sunday, 26 March 2017

Assignment of Ruby object_id

As we know that in ruby, nearly everything is an object and an object id is a unique identifier for that object. It is much like a fingerprint. All objects have an object id. In Ruby, the method .object_id returns an object’s unique identifier, which is presented by a number or a string of numbers.

For performance reasons true, false, nil and Fixnums are handled specially in ruby. For these objects there is a fixed value of object_id.

Let's check it on irb.

    2.3.0 :001 > false.object_id
     => 0
    2.3.0 :002 > true.object_id
     => 20
    2.3.0 :003 > nil.object_id
     => 8

Note that here we are using ruby 2.3.0. Value of true and nil object has changed from ruby 2.0.0. Before it is for true is 2 and for nil is 4.
You can get why it is changed from this link.

Now, what about fixnums?

Fixnums is in ruby also handled specially. Object id assignment to a fixnums is working on i*2+1.

    2.3.0 :004 > 1.object_id
     => 3
    2.3.0 :005 > 2.object_id
     => 5
    2.3.0 :006 > 3.object_id
     => 7

But, how it's works?

Ruby doesn't use the VALUE as a pointer in every instance. For Fixnums, Ruby stores the number value directly in the VALUE itself. That keeps us from having to keep a lookup table of every possible Fixnum in the system.

Actually, Fixnums are stored in the upper 31 bits, which means a shift left of one. Ruby use the lowest bit to mark that it is a Fixnum.

So, for example when we convert fixnum 4 into it's binary number. It will be 100.

Now, shift it to left and mark it is a fixnum. it will become now 1001. You can see that it is binary value of 9.

From above points, we can conclude that object_id of any other object like string or symbol always will be an even object_id.

No comments:

Post a Comment