In the article, we’re going to explore the following topics:
- what’s a symbol in Ruby?
- symbols behind the scene
What’s a Symbol in Ruby?
A symbol is a uniq instance of the
Symbol class which is generally used for identifying a specific resource. A resource can be:
- a method
- a variable
- a hash key
- a state
A symbol is uniq because only one instance of the
Symbol class can be created for a specific symbol in a running program
Here, we can see that the
:pending symbol is only created once as the two calls to
:pending.object_id return the same object identifier.
Symbols are often compared to strings. But the main difference between them relies on the fact that a new
String object is created for each called string — even if they’re identical
Now that we’re more familiar with symbols then let’s have a look to the
Symbol class and the API that it provides.
The Symbol class
This class is part of the Ruby’s Core Library (a.k.a the
This class is not publicly instantiable
NoMethodError (undefined method `new' for Symbol:Class)
Symbol object is implicitly instantiated when a new symbol is declared
Let’s have a look to its ancestor chain.
=> [Symbol, Comparable, Object, Kernel, BasicObject]
Symbol class inherits from the default parent class
Note that it includes the
This class shares the exact same ancestor chain as the
String and the
Feel free to read the
Ruby Object Modelarticle if you are unfamiliar with the
Objectclass and the ancestor chain.
Feel free to read
The Comparable modulearticle if you are unfamiliar with the
This class also provides a bunch of interesting instance methods to compare, modify and match symbols.
Most of the methods to modify and match symbols use the
Symbol#to_s method in order to work with the
String representation of the symbol.
Symbols behind the scene
As symbols are, for each of them, a uniq instance of the
Symbol class, then Ruby has to keep track of each of them to be able to ensure their uniqueness.
To do so, Ruby provides an internal table named
global_symbols which is in charge of keeping track of all the symbols of your running program.
Note that symbols are only put into memory once. This makes them very efficient to use. But they stay in memory until the program exits. This is true for all the Ruby versions < 2.2.0. Otherwise, Symbols are Garbage Collected.
Symbol.all_symbols method returns an array that represents the content of the
global_symbols table at the moment of the method call
First, we can see that the
global_symbols table is not empty.
In effect, at program setup, this table is filled in with all the methods, variables and classes included in the Ruby’s Core Library. These resources are inserted in the table as symbol.
For example, the
Structclass is part of the Ruby’s Core Library.
Then, we can see that a symbol that represents a resource is added to the
global_symbols table when we define:
- a new symbol
- a new variable
- a new method
- a new class/module
Then, we can see that no new symbol is added to the table when we re-open the
Hash class. This is because the
:Hash symbol is already included in the
global_symbols table. This mechanism is the same for symbols, variables and methods.
Note that this table is used any time that you’ve to deal with symbols.
Note that the
===operators are using an object-level comparison.
But for all the other comparison’s methods, it uses the string representation of the symbol for comparison.
feel free to check this C macro for further information
ONE MORE THING ⬇
Feel free to subscribe here: www.rubycademy.com
Thank you for taking the time to read this post :-)
Feel free to 👏 and share this article if it has been useful for you. 🚀
Also, as I post an article every 3 days, feel free to follow me to be notified of my new releases.
Here is a link to my last article:
The autoload Method in Ruby.