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"