Despite reading "Understanding Ruby Symbols", I'm still confused by the representation of the data in memory when it comes to using symbols. If a symbol, two of them contained in different objects, exist in the same memory location, then how is it that they contain different values? I'd have expected the same memory location to contain the same value.
This a quote from the link:
Unlike strings, symbols of the same name are initialized and exist in memory only once during a session of ruby
I don't understand how it manages to differentiate the values contained in the same memory location.
Consider this example:
patient1 = { :ruby => "red" }
patient2 = { :ruby => "programming" }
patient1.each_key {|key| puts key.object_id.to_s}
3918094
patient2.each_key {|key| puts key.object_id.to_s}
3918094
patient1
and patient2
are both hashes, that's fine. :ruby
however is a symbol. If we were to output the following:
patient1.each_key {|key| puts key.to_s}
Then what will be output? "red"
, or "programming"
?
Forgetting hashes for a second, I'm thinking a symbol is a pointer to a value. The questions I have are:
Consider this:
x = :sym
y = :sym
(x.__id__ == y.__id__ ) && ( :sym.__id__ == x.__id__) # => true
x = "string"
y = "string"
(x.__id__ == y.__id__ ) || ( "string".__id__ == x.__id__) # => false
So, however you create a symbol object, as long as its contents are the same, it will refer to the same object in memory. This is not a problem because a symbol is an immutable object. Strings are mutable.
(In response to the comment below)
In the original article, the value is not being stored in a symbol, it is being stored in a hash. Consider this:
hash1 = { "string" => "value"}
hash2 = { "string" => "value"}
This creates six objects in the memory -- four string objects and two hash objects.
hash1 = { :symbol => "value"}
hash2 = { :symbol => "value"}
This only creates five objects in memory -- one symbol, two strings and two hash objects.