object_id 1, 2, 3

  • Thread starter SpringFlowers AutumnMoon
  • Start date
S

SpringFlowers AutumnMoon

Fixnum object_id
0 1
1 3
2 5

-1 -1
-2 -3


so the question is... which objects have the object_id 2, 4, 6, and -2,
-4, etc?




irb(main):041:0> a = 0
=> 0
irb(main):042:0> a.object_id
=> 1

irb(main):043:0> a = 1
=> 1
irb(main):044:0> a.object_id
=> 3

irb(main):045:0> a = 2
=> 2
irb(main):046:0> a.object_id
=> 5

irb(main):047:0> a = -1
=> -1
irb(main):048:0> a.object_id
=> -1

irb(main):049:0> a = -2
=> -2
irb(main):050:0> a.object_id
=> -3
 
R

Rob Biedenharn

$ irb
irb(main):001:0> true.object_id
=> 2
irb(main):002:0> nil.object_id
=> 4
irb(main):003:0> false.object_id
=> 0

I saw a flowchart somewhere (online?) that showed how the least-
significant bits were used by the interpreter in the implementation
of some "objects" which were both common and immutable (TrueClass,
FalseClass, NilClass, Fixnum).

The LSB=1 is Fixnum (hence the object_id of n would be (n<<1)|0x01 in
the underlying C code).

-Rob

Fixnum object_id
0 1
1 3
2 5

-1 -1
-2 -3


so the question is... which objects have the object_id 2, 4, 6,
and -2,
-4, etc?




irb(main):041:0> a = 0
=> 0
irb(main):042:0> a.object_id
=> 1

irb(main):043:0> a = 1
=> 1
irb(main):044:0> a.object_id
=> 3

irb(main):045:0> a = 2
=> 2
irb(main):046:0> a.object_id
=> 5

irb(main):047:0> a = -1
=> -1
irb(main):048:0> a.object_id
=> -1

irb(main):049:0> a = -2
=> -2
irb(main):050:0> a.object_id
=> -3
--

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
S

SpringFlowers AutumnMoon

Rob said:
$ irb
irb(main):001:0> true.object_id
=> 2
irb(main):002:0> nil.object_id
=> 4
irb(main):003:0> false.object_id
=> 0

irb(main):063:0> 1000.object_id
=> 2001

irb(main):064:0> 1001.object_id
=> 2003

wonder where the 2002, 2004, etc go...
 
S

SpringFlowers AutumnMoon

Rob said:
I saw a flowchart somewhere (online?) that showed how the least-
significant bits were used by the interpreter in the implementation
of some "objects" which were both common and immutable (TrueClass,
FalseClass, NilClass, Fixnum).

The LSB=1 is Fixnum (hence the object_id of n would be (n<<1)|0x01 in
the underlying C code).


you mean the 2002, 2004, 20002, 20004, etc are all for other immutable
objects? what are they i wonder... the negative numbers have their own
negative object_id's.
 
T

Tim Hunter

SpringFlowers said:
Fixnum object_id
0 1
1 3
2 5

-1 -1
-2 -3


so the question is... which objects have the object_id 2, 4, 6, and -2,
-4, etc?

ex$ irb
irb(main):001:0> x = true
=> true
irb(main):002:0> x.object_id
=> 2
irb(main):003:0> x = false
=> false
irb(main):004:0> x.object_id
=> 0
irb(main):005:0> x = nil
=> nil
irb(main):006:0> x.object_id
=> 4

In other words, very small even values of object_id are reserved for
special values.
 
R

Rick DeNatale

ex$ irb
irb(main):001:0> x = true
=> true
irb(main):002:0> x.object_id
=> 2
irb(main):003:0> x = false
=> false
irb(main):004:0> x.object_id
=> 0
irb(main):005:0> x = nil
=> nil
irb(main):006:0> x.object_id
=> 4

In other words, very small even values of object_id are reserved for
special values.

One should keep in mind that these are interesting implementation
artifacts. I don't believe that there's any guarantee that such ids
would be the same in an arbitrary ruby implementation or even between
versions of the same implementation.
 
S

SpringFlowers AutumnMoon

One should keep in mind that these are interesting implementation
artifacts. I don't believe that there's any guarantee that such ids
would be the same in an arbitrary ruby implementation or even between
versions of the same implementation.

right, it is just from the curiosity standpoint. that where did those
even number object id's go? (the 10002, 10004, etc)
 
T

Tim Hunter

SpringFlowers said:
right, it is just from the curiosity standpoint. that where did those
even number object id's go? (the 10002, 10004, etc)

Object ids are memory addresses. Due to the way C programs (remember
Ruby is a C program) allocate memory, the object ids that are not
Fixnums and not very small even numbers are (at least in common systems)
always multiples of 8, so 10002 isn't going to be a real object id.
Also, because of the way operating systems dole out memory to C
programs, the memory addresses are usually going to be very large
numbers. (Mostly because operating systems like to reserve low memory
addresses for themselves.) Memory addresses are of course always
positive numbers, but Ruby displays object ids as signed numbers. If the
memory address is sufficiently large (such that the sign bit is set)
Ruby displays it as a negative number.

Of course at this point somebody will pipe up and say that what I just
wrote is untrue on such-and-such an obscure computer, and they'd be
right. I'm just talking about the kind of computers (PCs) and operating
systems (Win, Linux, etc.) that Ruby commonly runs on. Personally I'd be
interested in hearing about computers that Ruby runs on that don't act
this way.
 
R

Ryan Davis

Fixnum object_id
0 1
1 3
2 5

-1 -1
-2 -3


so the question is... which objects have the object_id 2, 4, 6,
and -2,
-4, etc?

ri ObjectSpace._id2ref
=> [false, 0, true, 1, nil, 2]
 
E

Eric Hodel

Also, because of the way operating systems dole out memory to C
programs, the memory addresses are usually going to be very large
numbers.
Of course at this point somebody will pipe up and say that what I just
wrote is untrue on such-and-such an obscure computer, and they'd be
right.

You don't need to go quite so far. OS X starts its heap at a low
memory address:

$ ruby -ve "p ''.object_id"
ruby 1.8.6 (2007-09-23 patchlevel 5000) [powerpc-darwin8.10.0]
1002180

$ ruby -ve "p ''.object_id"
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-freebsd6]
67351450

Also, the way ruby's heap is constructed, addresses will count down
then jump up to the next chunk of ruby heap slots (provided that no
GC is done):

$ ruby -e "p %w[a b].map { |o| o.object_id }"
[1002060, 1002050]

Also, on 64 bit platforms ruby objects are twice as big due to bigger
pointers and whatnot:

$ ruby -ve "p %w[a b].map { |o| o.object_id }"
ruby 1.8.5 (2006-08-25) [amd64-freebsd6]
[2789280, 2789260]
 
S

SpringFlowers AutumnMoon

Eric said:
You don't need to go quite so far. OS X starts its heap at a low
memory address:

$ ruby -ve "p ''.object_id"
ruby 1.8.6 (2007-09-23 patchlevel 5000) [powerpc-darwin8.10.0]
1002180

$ ruby -ve "p ''.object_id"
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-freebsd6]
67351450

Also, the way ruby's heap is constructed, addresses will count down
then jump up to the next chunk of ruby heap slots (provided that no
GC is done):

$ ruby -e "p %w[a b].map { |o| o.object_id }"
[1002060, 1002050]

so the object_id can be just the memory location of the object? does
Ruby keep a table to tell whether it is a memory location as opposed to

irb(main):003:0> 1000000.object_id
=> 2000001

which is not a memory location... in other words, when Ruby tries to
fetch the object, sometimes it will dereference 1002060 (fetch the
content there) but sometimes it won't, but just pretend that it is an
actual object?

I just realize that what if we extend the class Fixnum to have an extra
instance variable


class Fixnum
attr_accessor :foo
end

p 1.foo # nil

1.foo = 123
p 1.foo # 123
p 1.object_id # 3

so in this case, the object_id is not the memory location... and where
is the memory location? (for storing the instance variable)

I also found that you cannot do a

a = Fixnum.new
 
R

Rick DeNatale

Eric said:
You don't need to go quite so far. OS X starts its heap at a low
memory address:

$ ruby -ve "p ''.object_id"
ruby 1.8.6 (2007-09-23 patchlevel 5000) [powerpc-darwin8.10.0]
1002180

$ ruby -ve "p ''.object_id"
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-freebsd6]
67351450

Also, the way ruby's heap is constructed, addresses will count down
then jump up to the next chunk of ruby heap slots (provided that no
GC is done):

$ ruby -e "p %w[a b].map { |o| o.object_id }"
[1002060, 1002050]

so the object_id can be just the memory location of the object? does
Ruby keep a table to tell whether it is a memory location as opposed to

irb(main):003:0> 1000000.object_id
=> 2000001

which is not a memory location... in other words, when Ruby tries to
fetch the object, sometimes it will dereference 1002060 (fetch the
content there) but sometimes it won't, but just pretend that it is an
actual object?

I just realize that what if we extend the class Fixnum to have an extra
instance variable


class Fixnum
attr_accessor :foo
end

p 1.foo # nil

1.foo = 123
p 1.foo # 123
p 1.object_id # 3

so in this case, the object_id is not the memory location... and where
is the memory location? (for storing the instance variable)

For objects with immediate values, there is a global hash table which
maps the object_id to the location of the instance variables.

Note that "extend(ing) a class to have an extra instance variable" is
a bit misleading for Ruby.

Unlike many other OO languages instance variables in Ruby aren't
really associated with a class.
An instance acquires an instance variable not because it's a member of
a class, but because a method with that object as self was executed
which initialized it.

irb(main):001:0> class Fixnum
irb(main):002:1> attr_accessor :foo
irb(main):003:1> def foo_defined?
irb(main):004:2> defined? @foo
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> 1.foo_defined?
=> nil
irb(main):008:0> 1.foo = 123
=> 123
irb(main):009:0> 1.foo_defined?
=> "instance-variable"
irb(main):010:0> 2.foo_defined?
=> nil

This is true of all objects, not just immediates.

irb(main):011:0> class Glorp
irb(main):012:1> attr_accessor :bar
irb(main):013:1> def bar_defined?
irb(main):014:2> defined? @bar
irb(main):015:2> end
irb(main):016:1> end
=> nil
irb(main):017:0> g = Glorp.new
=> #<Glorp:0x5ba68>
irb(main):018:0> g.bar_defined?
=> nil
irb(main):019:0> g.bar = :fred
=> :fred
irb(main):020:0> g.bar_defined?
=> "instance-variable"
 
E

Eric Hodel

Eric said:
You don't need to go quite so far. OS X starts its heap at a low
memory address:

$ ruby -ve "p ''.object_id"
ruby 1.8.6 (2007-09-23 patchlevel 5000) [powerpc-darwin8.10.0]
1002180

$ ruby -ve "p ''.object_id"
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-freebsd6]
67351450

Also, the way ruby's heap is constructed, addresses will count down
then jump up to the next chunk of ruby heap slots (provided that no
GC is done):

$ ruby -e "p %w[a b].map { |o| o.object_id }"
[1002060, 1002050]

so the object_id can be just the memory location of the object? does
Ruby keep a table to tell whether it is a memory location as
opposed to

irb(main):003:0> 1000000.object_id
=> 2000001

For non-symbols and non-fixnums, it is the memory location of the
Object.

The table is:

static struct heaps_slot { /* ... */ } *heaps;

in gc.c.
which is not a memory location... in other words, when Ruby tries to
fetch the object, sometimes it will dereference 1002060 (fetch the
content there) but sometimes it won't, but just pretend that it is an
actual object?

See _id2ref in gc.c for how an id is turned into an Object.
I just realize that what if we extend the class Fixnum to have an
extra
instance variable

Instance variables are stored in a Hash that hangs off of the Object
for struct RObject-backed objects. There is a global hash for
everything else.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top