This program
class ObjectGarden
class << self.clone
puts self.object_id
end
end
puts ObjectGarden.clone.object_id
When run on Linux (have tested on RHEL) generates distinct object_id
s across multiple runs as I had expected. However when I run it on Windows, I get same output across multiple runs. And no matter what I do (hibernate/shutdown/"infamous blue screen" and restart) object_id
s won't change.
I also notice that object_id
on Windows changes iff I change the content (even an insignificant change like add a new line or comment) of the program.
Why is this difference between Windows and Linux implementations? And since I don't have access to OS X can someone please run it on a Mac and document the result.
I'm using Ruby 1.9.2-p136 on Windows and Ruby 1.9.2-p180 on Linux.
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With