Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to understand symbols in Ruby

Tags:

symbols

ruby

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:

  • Can I assign a value to a symbol?
  • Is a symbol just a pointer to a variable with a value in it?
  • If symbols are global, does that mean a symbol always points to one thing?
like image 531
Kezzer Avatar asked Feb 26 '10 13:02

Kezzer


People also ask

How do symbols work in Ruby?

Ruby symbols are defined as “scalar value objects used as identifiers, mapping immutable strings to fixed internal values.” Essentially what this means is that symbols are immutable strings. In programming, an immutable object is something that cannot be changed.

What does :: mean in Ruby?

The use of :: on the class name means that it is an absolute, top-level class; it will use the top-level class even if there is also a TwelveDaysSong class defined in whatever the current module is.

What does @variable mean in Ruby?

In Ruby, the at-sign ( @ ) before a variable name (e.g. @variable_name ) is used to create a class instance variable.

What does %I mean in Ruby?

The usage of "%I" is just to create hash keys from an array of strings, separated by whitespaces.


2 Answers

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.

like image 75
anshul Avatar answered Sep 29 '22 14:09

anshul


I was able to grock symbols when I thought of it like this. A Ruby string is an object that has a bunch of methods and properties. People like to use strings for keys, and when the string is used for a key then all those extra methods aren't used. So they made symbols, which are string objects with all the functionality removed, except that which is needed for it to be a good key.

Just think of symbols as constant strings.

like image 45
Segfault Avatar answered Sep 29 '22 13:09

Segfault