Faruk Nasir
Faruk's Zone

Faruk's Zone

Ruby: Lets talk Symbols

Photo by Joshua Fuller on Unsplash

Ruby: Lets talk Symbols

The idea of symbols in ruby speaks to the whole concept of immutable strings. A symbol is a unique instance of the `Symbol` class which is generally u

Faruk Nasir's photo
Faruk Nasir
·Oct 10, 2020·

4 min read

Subscribe to my newsletter and never miss my upcoming articles

Table of contents

  • What are symbols
  • Symbols or Strings
  • Using Symbols to create hashes

The other day, while I was reading an open source code, I kept seeing names with a colon in front of them. I just started with Ruby and I have been hooked. There is a lot i'm still not privy to semantically and syntactically. So, I tried guessing at first what those coloned-names represented. A special variable? Pointers? No, It can't be pointers. I doubt there is the concept of pointers in an interpreted language like Ruby. Scoped variable? maybe? or, maybe, global variable?

I got tired of guessing and consulted the omniscient google. Long story short, I learnt something new and I'm sharing it in this post.

What are symbols

The idea of symbols in ruby speaks to the whole concept of immutable strings. A symbol is a unique instance of the Symbol class which is generally used for identifying a resource, that is, a method, a variable, a hashkey etc. It is unique, meaning, no matter where it appears in your program, a particular symbol have the same value.

You can think of Symbols as, basically, strings that are immutable and, usually, represent something else.

Checkout the following code snippet. It is a usual representation of an associative array in php. right? So, in there, we have machine level strings recently_lost, recently_found as keys to represent associated values Recently lost and Recently found respectively. We use those strings as pseudo-keys to dynamically get their associated values.

Symbol is the dedicated structure built to encapsulate this idea in ruby.

$statuses = [
    'recently_lost' => 'Recently lost',
    'recently_found' => 'Recently found',
];
Ruby uses symbols, and maintains a Symbol Table to hold them. Symbols are names - names of instance variables, names of methods, names of classes. So if there is a method called control_movie, there is automatically a symbol :control_movie. Ruby's interpreted, so it keeps its Symbol Table handy at all times. You can find out what's on it at any given moment by calling Symbol.all_symbols. (Fabio Akita @ rubylearning.com)

Symbols can be stored in variables just like strings can:

status = :lost

They can be converted to string and vice versa:

:lost.to_s
# 'lost'

'lost'.to_sym
# :lost

Symbols or Strings

Symbols are often compared to strings. The main difference between them relies on the fact that a new String object is called for each string even if they are identical.

With strings, every time it appears in a program, a new object is created on its behalf. In the case of symbols, after creation, all other subsequent ones will reference the first one. This saves both time and memory. Let's investigate this claim:

"faruk".object_id
# 100
"faruk".object_id
# 200

Now do the same with symbols:

:name.object_id
# 71068
:name.object_id
# 71068

Attempting mutate a symbol will throw a NoMethodError:

:lost.concat(' soul')

# Traceback (most recent call last):
#         4: from /Users/faruk/.rbenv/versions/2.7.2/bin/irb:23:in `<main>'
#         3: from /Users/faruk/.rbenv/versions/2.7.2/bin/irb:23:in `load'
#         2: from /Users/faruk/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
#         1: from (irb):8
# NoMethodError (undefined method `concat' for :lost:Symbol)

If the contents of the object are of more importance, use string. If the identity of the object is more important, use a symbol.

Using Symbols to create hashes

Hashes (sometimes known as associative arrays, maps, or dictionaries) are similar to arrays in that they are indexed collection of object references. However, while you index arrays with integers, you can index a hash with objects of any types: strings, regular expressions, and so on. When you store a value in a hash, you actually supply two objects - the index (normally called the key) and the value. You can subsequently retrieve the value by indexing the hash with the same key. The values in a hash can be objects of any type. (rubylearning.com)

In the event that you use a quoted string as a key of a hash value, it is advised that you use a symbol as in the following:

user = Hash.new

user[:name] = 'Faruk'
user[:gender] = 'Male'
user[:age] = 27

puts user[:name] # Faruk

This will greatly help with memory usage and performance. Especially in large applications dealing with huge amount of data.

And, that's all folks! Thank you for reading.

NB: If you want to share your thoughts with me concerning this post, please shoot an email to me: faruk@starfolksoftware.com
 
Share this