When I started learning Ruby, I was confused between strings and symbols. The purpose of symbols was quite unclear. I found myself asking this question over and over again, if symbols and strings both can be used interchangeably, why use symbols at all? It was later that I realized the elegance of symbols and the differences between the two - String
and Symbol
.
What are Strings ?
Anything inside the quotations is a string. They are the instances of String
class.
'Hi! I am a string in single quotations.'
"Hi! I am also a string but in double quotations."
What are Symbols ?
Symbols are instances of class Symbol
. They can be identified by :
in front of them.
:a_symbol
:another_symbol
Symbols and Strings are often seen used interchangeably, but they are actually quite different.
-
Symbols are immutable. You cannot append another symbol to an existing symbol and create a new symbol.
irb(main):171:0> :a << :b NoMethodError: undefined method `<<' for :a:Symbol
Strings are mutable. You can append another string to an existing string and create a new string.
irb(main):005:0> "a" << "b" => "ab"
-
Symbols are unique. Same symbol will always represent the same object. Symbols are saved in
symbol_table
, every time we try to access a symbol, it is retrieved from the table, hence pointing to the same symbol.irb(main):041:0> var1 = :a => :a irb(main):042:0> var2 = :a => :a irb(main):043:0> var1.object_id => 723868 irb(main):044:0> var2.object_id => 723868 # var1 and var2 are pointing to the same object
Strings are not unique . Same strings may represent different object. Creating two strings may result is creation of a new instance of class
String
for each.irb(main):045:0> var3 = "a" => "a" irb(main):046:0> var4 = "a" => "a" irb(main):047:0> var3.object_id => 70276725479300 irb(main):048:0> var4.object_id => 70276725462500 #var3 and var4 are pointing to different objects
-
The presence of a symbol cannot be tested using
include?
method. As soon as you executeinclude?
, it adds the symbol to thesymbol_table
and returnstrue
. In order to test a symbol, we need to usegrep
.irb(main):050:0> Symbol.all_symbols.grep(/pqr/) => [] irb(main):052:0> Symbol.all_symbols.include?(:pqr) => true
Strings can be tested using
include?
method.irb(main):006:0> "I am a string pqr".include?("pqr") => true
-
As stated above, Symbols are saved in
symbol_table
. Every time a new symbol is created, it is stored in the table.irb(main):010:0> Symbol.all_symbols.count => 3488 irb(main):011:0> :new_symbol => :new_symbol irb(main):012:0> Symbol.all_symbols.count => 3489 #=> count increased by 1
String have no such table.
-
Finally, Ruby can process Symbols faster because no new memory is allocated when they are referenced elsewhere.
Ruby processes strings slower than symbols.
These are few important differences between Symbols and Strings.