Os símbolos são identificadores com nome que podem ser usados para fazer referência a um valor.
Os símbolos são criados através de um literal de símbolo, que consiste em prefixar um nome com o caráter :, p. ex. :foo.
Também podem ser escritos com aspas, p. ex. :"foo", o que permite, por exemplo, espaços no nome.
:foo # => :foo
:"foo boo" # => :"foo boo"
Os símbolos são usados em muitos sítios da linguagem, incluindo como chaves em hashes, para representar nomes de métodos e nomes de variáveis.
O que distingue os símbolos das strings é o facto de serem identificadores, que não representam dados nem texto. Isto significa que dois símbolos 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
Os símbolos são imutáveis, o que significa que não podem ser modificados. Isto significa que, quando "modificas" um símbolo, estás na verdade a criar um novo símbolo. Existem alguns métodos que podem ser usados para manipular símbolos, e todos devolvem novos símbolos. Podes encontrar todos os métodos na API do Symbol.
:foo.upcase # => :FOO
:foo.object_id # => 1086748
:foo.upcase.object_id # => 60
A vantagem de os símbolos serem imutáveis é que são mais eficientes em termos de memória do que as strings, mas também mais seguros de usar como identificadores.
Os símbolos podem ser convertidos em strings e vice-versa.
Isto pode ser útil quando queres modificar um símbolo, ou quando queres usar um símbolo como string.
Para apresentar uma string como símbolo, podes usar o método String#to_sym, e para fazer o contrário, podes usar o método Symbol#to_s.
Uma vez que os símbolos têm um conjunto limitado de métodos, pode ser útil converter um símbolo numa string para usar métodos de string sobre ele, se for preciso um novo símbolo.
:foo.to_s # => "foo"
"foo".to_sym # => :foo
Em Ruby, podes obter nomes em âmbitos usando vários métodos para obter nomes de constantes, métodos e variáveis. Estes métodos devolvem arrays de símbolos.
Alguns 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]
Podes encontrar todos os métodos na API do Kernel e na API do Module.