Skip to content

Symbol

A Symbol represents a unique name inside the entire source code.

Symbols are interpreted at compile time and cannot be created dynamically. The only way to create a Symbol is by using a symbol literal, denoted by a colon (:) followed by an identifier. The identifier may optionally be enclosed in double quotes (").

:unquoted_symbol
:"quoted symbol"
:"a" # identical to :a
:あ

A double-quoted identifier can contain any unicode character including white spaces and accepts the same escape sequences as a string literal, yet no interpolation.

For an unquoted identifier the same naming rules apply as for methods. It can contain alphanumeric characters, underscore (_) or characters with a code point greater than 159(0x9F). It must not start with a number and may end with an exclamation mark (!) or question mark (?).

:question?
:exclamation!

All Crystal operators can be used as symbol names unquoted:

:+
:-
:*
:/
:%
:&
:|
:^
:**
:>>
:<<
:==
:!=
:<
:<=
:>
:>=
:<=>
:===
:[]
:[]?
:[]=
:!
:~
:!~
:=~

Internally, symbols are implemented as constants with a numeric value of type Int32.

Percent symbol array literal

Besides the single symbol literal, there is also a percent literal to create an Array of symbols. It is indicated by %i and a pair of delimiters. Valid delimiters are parentheses (), square brackets [], curly braces {}, angles <> and pipes ||. Except for the pipes, all delimiters can be nested; meaning a start delimiter inside the string escapes the next end delimiter.

%i(foo bar baz)  # => [:foo, :bar, :baz]
%i(foo\nbar baz) # => [:"foo\nbar", :baz]
%i(foo(bar) baz) # => [:"foo(bar)", :baz]

Identifiers may contain any unicode characters. Individual symbols are separated by a single space character, which must be escaped to use it as a part of an identifier.

%i(foo\ bar baz) # => [:"foo bar", :baz]