On 5/20/07, Brian Candler <B.Candler / pobox.com> wrote:
> On Sun, May 20, 2007 at 10:18:22AM +0900, Rick DeNatale wrote:
> > On 5/19/07, Brian Candler <B.Candler / pobox.com> wrote:
> > >On Sat, May 19, 2007 at 08:28:24AM +0900, Rick DeNatale wrote:
> >
> > >> Ruby symbols are represented by a value computed by shifting the
> > >> symbols integer representation left 8 bits and setting the low-order
> > >> byte to 0xFF representation
> > >
> > >Perhaps it varies based on the Ruby version you're running; it's not like
> > >that for me.
> > >
> > >irb(main):006:0> :foo.object_id.to_s(16)
> > >=> "39490e"
> > >irb(main):007:0> RUBY_VERSION
> > >=> "1.8.4"
> >
> > You can't really see the internal bit representations from ruby, since
> > they get manipulated before you see them.  Much like the class of an
> > object reported by ruby isn't the same as the object pointed to by its
> > klass pointer at the C level.
> >
> > And even if you could, I was talking about the integer representation
> > of the symbol, not the object_id.
>
> AFAIK, the object_id is the in-memory pointer to the structure of the object
> (if it's a material object), or is one of the special values:
>
> - 0, 2 or 4 for false, true or nil
>
> - (n<<1) | 1 for Fixnums

Not starting with 1.8.5
VALUE
rb_obj_id(VALUE obj)
{
    /*
     *                32-bit VALUE space
     *          MSB ------------------------ LSB
     *  false   00000000000000000000000000000000
     *  true    00000000000000000000000000000010
     *  nil     00000000000000000000000000000100
     *  undef   00000000000000000000000000000110
     *  symbol  ssssssssssssssssssssssss00001110
     *  object  oooooooooooooooooooooooooooooo00        = 0 (mod sizeof(RVALUE))
     *  fixnum  fffffffffffffffffffffffffffffff1
     *
     *                    object_id space
     *                                       LSB
     *  false   00000000000000000000000000000000
     *  true    00000000000000000000000000000010
     *  nil     00000000000000000000000000000100
     *  undef   00000000000000000000000000000110
     *  symbol   000SSSSSSSSSSSSSSSSSSSSSSSSSSS0        S...S % A = 4
(S...S = s...s * A + 4)
     *  object   oooooooooooooooooooooooooooooo0        o...o % A = 0
     *  fixnum  fffffffffffffffffffffffffffffff1        bignum if required
     *
     *  where A = sizeof(RVALUE)/4
     *
     *  sizeof(RVALUE) is
     *  20 if 32-bit, double is 4-byte aligned
     *  24 if 32-bit, double is 8-byte aligned
     *  40 if 64-bit
     */
    if (TYPE(obj) == T_SYMBOL) {
        return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
    }
    if (SPECIAL_CONST_P(obj)) {
        return LONG2NUM((long)obj);
    }
    return (VALUE)((long)obj|FIXNUM_FLAG);
}

1.8.6 and 1.9 have the same code.


-- 
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/