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 (").

  1. :unquoted_symbol
  2. :"quoted symbol"
  3. :"a" # identical to :a
  4. :あ

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 (?).

  1. :question?
  2. :exclamation!

All Crystal operators can be used as symbol names unquoted:

  1. :+
  2. :-
  3. :*
  4. :/
  5. :%
  6. :&
  7. :|
  8. :^
  9. :**
  10. :>>
  11. :<<
  12. :==
  13. :!=
  14. :<
  15. :<=
  16. :>
  17. :>=
  18. :<=>
  19. :===
  20. :[]
  21. :[]?
  22. :[]=
  23. :!
  24. :~
  25. :!~
  26. :=~

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.

  1. %i(foo bar baz) # => [:foo, :bar, :baz]
  2. %i(foo\nbar baz) # => [:"foo\nbar", :baz]
  3. %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.

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