A symbol looks like a variable name but it's prefixed with a colon. Examples - :action, :line_items. You don't have to pre-declare a symbol and they are guaranteed to be unique. There's no need to assign some kind of value to a symbol - Ruby takes care of that for you. Ruby also guarantees that no matter where it appears in your program, a particular symbol will have the same value.
Alternatively, you can consider the colon to mean "thing named" so :id is "the thing named id." You can also think of :id as meaning the name of the variable id, and plain id as meaning the value of the variable.
A Symbol is the most basic Ruby object you can create. It's just a name and an internal ID. Symbols are useful because a given symbol name refers to the same object throughout a Ruby program. Symbols are more efficient than strings. Two strings with the same contents are two different objects, but for any given name there is only one Symbol object. This can save both time and memory.
Refer the example: p039symbol.rb below
- # p039symbol.rb
- # use the object_id method of class Object
- # it returns an integer identifier for an object
- puts "string".object_id
- puts "string".object_id
- puts :symbol.object_id
- puts :symbol.object_id
The output when I ran the program on my PC was:
- >ruby p039symbol.rb
- 21066960
- 21066930
- 132178
- 132178
- >Exit code: 0
Therefore, when do we use a string versus a symbol?
- If the contents (the sequence of characters) of the object are important, use a string
- If the identity of the object is important, use a symbol
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.
A Symbol object is created by prefixing an operator, string, variable, constant, method, class, module name with a colon. The symbol object will be unique for each different name but does not refer to a particular instance of the name, for the duration of a program's execution. Thus, if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.
A Symbol object is created by prefixing an operator, string, variable, constant, method, class, module name with a colon. The symbol object will be unique for each different name but does not refer to a particular instance of the name, for the duration of a program's execution. Thus, if Fred is a constant in one context, a method in another, and a class in a third, the Symbol :Fred will be the same object in all three contexts.
This can be illustrated by this simple program - p039xsymbol.rb:
- # p039xsymbol.rb
- class Test
- puts :Test.object_id.to_s
- def test
- puts :test.object_id.to_s
- @test = 10
- puts :test.object_id.to_s
- end
- end
- t = Test.new
- t.test
The output when I ran the program on my PC was:
- >ruby p039xsymbol.rb
- 116458
- 79218
- 79218
- >Exit code: 0
Here is another example - p039xysymbol.rb:
- # p039xysymbol.rb
- know_ruby = :yes
- if know_ruby == :yes
- puts 'You are a Rubyist'
- else
- puts 'Start learning Ruby'
- end
The output is:
- >ruby p039xysymbol.rb
- You are a Rubyist
- >Exit code: 0
In this example, :yes is a symbol. Symbols don't contain values or objects, like variables do. Instead, they're used as a consistent name within code. For example, in the preceding code you could easily replace the symbol with a string, as in example - p039xyzsymbol.rb
- # p039xyzsymbol.rb
- know_ruby = 'yes'
- if know_ruby == 'yes'
- puts 'You are a Rubyist'
- else
- puts 'Start learning Ruby'
- end
This gives the same result, but isn't as 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.
We can also transform a String into a Symbol and vice-versa:
- puts "string".to_sym.class # Symbol
- puts :symbol.to_s.class # String
Symbols are particularly useful when creating hashes and you want to have a distinction between keys and values.