What is a symbol in ruby

Symbol is like a variable but it’s prefixed with a colon(:). Symbols are Strings, an important difference is, Symbols are immutable. Mutable objects can be changed after assigning while immutable objects can only be overwritten. It also means only one copy of a symbol needs to be created. Thus, if you have

var_1 = :my_symbol
var_2 = :my_symbol

:my_symbol will only be created once, and var_1 and var_2 point to the same area of memory. On the other hand, if you have

var_1 = "my_symbol"
var_2 = "my_symbol"

a string containing my_symbol will be created twice, and var_1 and var_2 will point to different instances.

#object_id- Returns an integer identifier for obj
puts "my_symbol".object_id    # 43900321
puts "my_symbol".object_id    # 53284673
puts :my_symbol.object_id     # 342943
puts :my_symbol.object_id     # 342943

So, when do we use a string and a symbol?

  • If the identity of an object is important, use a symbol.
  • If the contents of an object are important, use a string.

symbol_obj = :yes
if symbol_obj == :yes
  print "You understood symbols"
else 
  print "Spend more time to understand symbols"
string_obj = "yes"
if string_obj == "yes"
  print "You understood the difference between symbol and string"
else 
  print "Spend more time to understand symbols"

This gives the same result, but is it efficient?

In this example, every mention of ‘yes’ creates a new object stored separately in memory, whereas symbols are single reference values that are only initialized once. In the first code example, only :yes exists, whereas in the second example you end up with the full strings of ‘yes’ and ‘yes’ taking up memory.

Advantages of using symbols:

  1. A Ruby symbol is an object with O(1) comparison
ALSO READ  custom form yii php

To compare two strings, we potentially need to look at every character. For two strings of length N, this will require N+1 comparisons

def string_compare str1, str2
  if str1.length != str2.length
        return false
  end
  for i in 0...str1.length
    return false if str1[i] != str2[i]
  end
  return true
end
string_compare "foobar", "foobar"

But since every appearance of :foobar refers to the same object, we can compare symbols by looking at object IDs. We can do this with a single comparison.(O(1))

def symbol_compare sym1, sym2
  sym1.object_id == sym2.object_id
end
symbol_compare :foobar, :foobar

2. A Ruby symbol is a label in a free-form enumeration

In C++, we can use “enumerations” to represent families of related constants:

enum BugStatus { OPEN, CLOSED };
BugStatus original_status = OPEN;
BugStatus current_status  = CLOSED;

But because Ruby is a dynamic language, we don’t worry about declaring a BugStatus type, or keeping track of the legal values. Instead, we represent the enumeration values as symbols:

original_status = :open
current_status  = :closed

3. A Ruby symbol is a constant, unique name

In Ruby, we can change the contents of a string:

"foobar"[0] = ?b # "boo"

But we can’t change the contents of a symbol:

:foobar[0]  = ?b # Raises an error

4. A Ruby symbol is the keyword for a keyword argument

When passing keyword arguments to a Ruby function, we specify the keywords using symbols:

# Build a URL for 'bug' using Rails.
url_for :controller => 'bug',
        :action => 'show',
        :id => bug.id

5. A Ruby symbol is an excellent choice for a hash key

Typically, we’ll use symbols to represent the keys of a hash table:

options = {}
options[:auto_save]     = true
options[:show_comments] = false

 

 

Leave a Reply