From: Gavin Sinclair Date: 2002-10-13T09:15:01+09:00 Subject: Re: Things That Newcomers to Ruby Should Know Interesting; thanks! Gavin From: "William Djaja Tjokroaminata" > Hi Gavin, > > That's because 1000000001 still can fit in Fixnum, so Ruby calls INT2FIX > which simply left-shift by one and set the least significant bit to > 1. When you call "id", unless the object is a special constant, Ruby > simply set the least significant bit to 1, and return the "VALUE" of the > object (which for a Fixnum is the object itself). Because the least > significant bit is always set to 1 (unless probably for special > constants), you will always see odd numbers for id's. > > So for all objects of type Fixnum, its id is simply given by left shift by > one and set least significant bit to 1, which is simply equivalent to > multiply by two and add 1. > > When you call "1000000001.id.class", the "class" method of > "1000000001.id" is called; because in this case 2000000003 does not > fit into a Fixnum, Ruby creates a Bignum, and returns its class. > > So the id's are not predefined (not stored in memory), but created > (computed) as necessary based on the simple formula above. > > Finally, when you ran the successive testlets and you found many more > objects, I guess it is just because the testlet itself creates many more > Ruby (temporary) objects, which exist until the next gc cycle. > > Regards, > > Bill > ============================================================================ > Gavin Sinclair wrote: > > When I discovered this some time ago, I wondered deeply what might be occupying > > id #s 2, 4, 6, ... > > > Interesting that "id" is documented in 'ri' to return a Fixnum, but: > > 1000000001.id => 2000000003 > > 1000000001.id.class => Bignum > > > I'm surprised that numbers that high have a predictable ID, as if they're > > predefined. But then maybe the numbers are brought into being only as needed > > (except for the first 100, like Python), with a special case formulaic approach > > to assigning them an ID, and then all non-Integers are given an even ID so they > > don't clash. When I ran > > > a = [] > > ObjectSpace.each_object { |obj| a << obj } > > a.find { |obj| obj.id % 2 == 1 } > > > it returned nil, so that must be the case. > > > What I also found interesting was that successive runs of this testlet seemed > > to produce many more objects. > > > Any comments? > > > Gavin > > >