Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are symbols and how do we use them?

Tags:

symbols

ruby

I do not understand what a symbol table is. Can someone help me understand symbols, from the very basics and explain thoroughly.

like image 377
Wei Lie Sho Avatar asked Jul 19 '11 09:07

Wei Lie Sho


People also ask

How are symbols useful to us?

They give a lot of information in a limited space. With the use of symbols, maps can be drawn easily and are simple to read, even if we don't know the language of an area and therefore cannot ask someone for directions. We can collect information from maps with the help of symbols.

What do you mean by symbols?

1 : something that stands for something else : emblem The eagle is a symbol of the United States. 2 : a letter, character, or sign used instead of a word to represent a quantity, position, relationship, direction, or something to be done The sign + is the symbol for addition. symbol.

What are symbols in simple words?

something used for or regarded as representing something else; a material object representing something, often something immaterial; emblem, token, or sign. 2. a letter, figure, or other character or mark or a combination of letters or the like used to designate something.


2 Answers

The most basic usage of Symbols is well summarized with phrase: "A Symbol is a constant integer with human readable name" (by Wei Lie Sho).

If in C you type this:

#define USER 1
#define ADMIN 2
#define GUEST 3
[...]
user.type = ADMIN;

then in ruby you just use a Symbol:

user.type = :admin

So, a Symbol in ruby is just some value, in which the only important thing is the name, or put in other words: the value of the Symbol is its name.

The main difference between Symbols and Strings (because this is also correct code: user.type = "admin") is that Symbols are fast. The main difference between Symbols and integers (used as in this example) is that the Symbols are easily readable for the programmer, while integers are not.

Other Symbol properties are not crucial for their basic usage.


While there is some integer value associated with Symbols (for example: .object_id), you should not rely on it. In each run of your program the integer value of a given Symbol may be different. However, while your program runs, each (let's call it so) "instance" of the same Symbol will have the same integer value.

Unlike the integer constants (as in the C example) the Symbols cannot be sorted in Ruby 1.8 - they do not know whether one is greater than another.

So, you can match Symbols (for equality) as quick as integers are matched, but you cannot sort Symbols directly in Ruby 1.8. Of course, you can sort the String equivalents of Symbols:

if user.type == :admin # OK
if user.type > :guest # will throw an exception.

[:two, :one].sort # will throw an exception
[:two, :one].sort_by {|n| n.to_s} # => [:one, :two]

One of the important properties of Symbols is that once a Symbol is encountered in the program (typed in the source code or created 'on-the-fly'), its value is stored until the end of the program, and is not garbage-collected. That's the "Symbol-table" you mentioned.

If you create a lot of unique Symbols in your program (I talk about millions), then it is possible that your program will run out of memory.

So, a rule of thumb is: "Never convert any user supplied value to Symbols".

# A Rails-like example:
user.role = params["role"].to_sym # DANGEROUS!

I believe this set of information may be sufficient for using Symbols efficiently in Ruby.


Note that in Ruby 1.9 Symbols include Comparable, and so you can do things like

p :yay if :foo > :bar 
like image 60
Arsen7 Avatar answered Sep 19 '22 06:09

Arsen7


A ruby symbol is a pointer to a place in memory where there is a constant string. And all identical symbols point to the same place in memory.

A pointer is just an integer representing an address in memory, where addresses in memory are much like the addresses of houses in a city. And each address is unique. In effect, ruby transforms each symbol into a single integer: the address of a constant string in memory.

In order for ruby to compare two strings, ruby starts with the first letter of each string and compares their ascii codes. If they are the same, then ruby moves on to the second letter of each string to compare their ascii codes--until ruby finds a difference in the ascii codes or the end of one of the strings is reached. For instance, with these two strings:

"hello_world_goodbye_mars"
"hello_world_goodbye_max"

ruby has to compare each letter of the two strings until if finds a difference at 'r' and 'x' in order to tell that the strings are not the same.

On the other hand, ruby only has to make one comparison when comparing symbols--no matter how long the symbol is. Because a symbol is effectively just a single integer, in order for ruby to tell whether the following two symbols are different:

:hello_world_goodbye_mars
:hello_world_goodbye_max

ruby only has to do one comparison: the integer representing the first symbol v. the integer representing the second symbol; and the comparison becomes something like:

if 245678 == 345789
  #then the symbols are the same
else
  #the symbols are not the same
end

In other words, comparing two symbols only requires comparing two integers, while comparing strings can require comparing a series of integers. As a result, comparing symbols is more efficient than comparing strings.

Symbols that are different are each given unique integers. Identical symbols are given identical integers.

Disclaimer: any factual errors with the above description will not harm you in any way.

like image 22
7stud Avatar answered Sep 21 '22 06:09

7stud