Symbols são identificadores nomeados que podem ser usados para se referir a um valor.
Symbols são criados por meio de um literal de symbol, que consiste em prefixar um nome com o caractere :, por exemplo :foo.
Eles também podem ser escritos entre aspas, por exemplo :"foo", o que permite, por exemplo, espaços no nome.
:foo # => :foo
:"foo boo" # => :"foo boo"
Symbols são usados em muitos lugares na linguagem, inclusive como chaves em hashes, para representar nomes de métodos e de variáveis.
O que diferencia os symbols das strings é que eles são identificadores e não representam dados nem texto. Isso significa que dois symbols com o mesmo nome são sempre o mesmo objeto.
"foo".object_id # => 60
"foo".object_id # => 80
:foo.object_id # => 1086748
:foo.object_id # => 1086748
Symbols são imutáveis, ou seja, não podem ser modificados. Isso significa que, quando você "modifica" um symbol, na verdade está criando um novo symbol. Existem alguns métodos que podem ser usados para manipular symbols, e todos eles retornam novos symbols. Todos os métodos podem ser encontrados na Symbol API.
:foo.upcase # => :FOO
:foo.object_id # => 1086748
:foo.upcase.object_id # => 60
A vantagem de os symbols serem imutáveis é que eles são mais eficientes em memória do que as strings, além de serem mais seguros para usar como identificadores.
Symbols podem ser convertidos em strings e vice-versa.
Isso pode ser útil quando você quer modificar um symbol ou quando quer usar um symbol como string.
Para apresentar uma string como symbol, você pode usar o método String#to_sym; para fazer o contrário, use o método Symbol#to_s.
Como os symbols têm um conjunto limitado de métodos, pode ser útil converter um symbol em string para usar métodos de string nele, caso um novo symbol seja necessário.
:foo.to_s # => "foo"
"foo".to_sym # => :foo
No Ruby, você pode obter nomes em escopos usando vários métodos que retornam nomes de constantes, métodos e variáveis. Esses métodos retornam arrays de symbols.
Alguns desses métodos são Module#constants, Module#instance_methods, Module#class_variables, global_variables e local_variables.
module Foo
BAR = 1
def self.baz; end
end
a = 1
Foo.constants # => [:BAR]
Foo.instance_methods # => [:baz]
local_variables # => [:a]
Todos os métodos podem ser encontrados na Kernel API e na Module API.