What is a symbol in Ruby?
Two of the most common questions Ruby developers get asked are “What is the difference between a string and a symbol?” and “Why would you use a symbol instead of a string?
Syntactically, strings are any text written between quotation marks (“this is a string”, ‘so is this’, `this too!`), while a symbol is text that begins with a colon (:symbol). But strings and symbols have different functionality that make them useful for different purposes in programming.
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. When you create an immutable object, it will remain the same until it is destroyed:
In the above example, I was able to change the value of the str variable by concatenating a new string to it. When I tried to do this to the sym variable, I got an undefined method error message, because symbols are immutable!
Why use symbols over strings?
The immutable nature of symbols makes them very valuable in programming because mutable objects can cause bugs that are difficult to detect. Since symbols stay the same, using them helps to avoid this issue.
Another significant difference between strings and symbols is how they are stored in memory. Check out the object IDs in the example below:
Every time a string is written, it creates a new object with a new place in memory, even if the string is textually identical to an existing string. However, since symbols are immutable, they always refer to the same object and the same place in memory.
Strings can hurt a program’s performance if string objects are repeatedly created and destroyed when the same object could have been reused in their place. For this reason, a program that uses symbols over strings (when possible) will run more efficiently.
When to use symbols?
The late Ruby guru Jim Weirich (this guy was seriously an amazing programmer. He invented Rack!) summed up the different uses for strings and symbols: “If the textual content of the object is important, use a String. If the identity of the object is important, use a Symbol.”
Symbols come in handy when you need a unique identifier to hold a value, such as a key in a hash. If you use strings as hash keys, you run into the same issues with mutability and memory (different objects/places in memory):
Using symbols as hash keys eliminates this issue:
Note the different syntax for using symbols as hash keys on lines 001 and 002. This is just some Ruby syntactic sugar; the keys are functionally the same. In both constructions, you would access the value with person[:name] or person2[:name].
Symbols are objects that can be passed around like any other Ruby object. They can also be used to pass values to methods, such as in getter and setter methods in class definitions:
These are just a few examples of when to use symbols in Ruby. When in doubt, if a value does not need to change, use a symbol instead of a string.