For most objects in ruby, the number you get from #object_id
is actually the pointer to the internal C data structure for the object. This data structure in turn has space allocated for it by whatever memory allocator the ruby implementation/build uses.
Without reading code, I will guess that the linux version is producing different results every time because something, either ruby or the C allocator, is intentionally using a random offset for allocations or pointers, to make them hard to guess and thus make the program more secure.
There is only one guarantee that ruby will make about object_id
's: as long as a particular object exists, its object_id
will be unique to that ruby interpreter and will not change. That's all. You can even get the same object_id
for an object as one that was created previously and later garbage collected, if it ends up getting the same chunk of memory.
Note also, if you do something like this:
irb(main):001:0> a = "hi"
=> "hi"
irb(main):002:0> a.object_id
=> 14348380
irb(main):003:0> a = a + " there"
=> "hi there"
irb(main):004:0> a.object_id
=> 14197020
The line a = a + " there"
actually creates a new object, with a new object_id
, where as using #concat
doesn't:
irb(main):005:0> a = "hi"
=> "hi"
irb(main):006:0> a.object_id
=> 12031400
irb(main):007:0> a.concat " there"
=> "hi there"
irb(main):008:0> a.object_id
=> 12031400
Note also that in ruby, assignment binds the assigned variable to the object, so assigning one variable to another points them both at the same object:
irb(main):011:0> a = "hi"
=> "hi"
irb(main):012:0> a.object_id
=> 12081640
irb(main):013:0> b = a
=> "hi"
irb(main):014:0> b.object_id
=> 12081640
So changing one variable will change the other:
irb(main):015:0> a.concat " there"
=> "hi there"
irb(main):016:0> b
=> "hi there"