Elixir Sigils

Welcome to a tutorial on Sigils in Elixir.

Sigils are mechanisms provided by the language for working with textual representations. Sigils always start with the tilde (~) character which is followed by a letter (it identifies the sigil) and then a delimiter. But, optionally, modifiers can be added after the final delimiter later.

 

Regex

In Elixir, Regexes are sigils. In the tutorial on String, we saw how Regex is used. Check out the example below on Regex

# A regular expression that matches strings which contain "foo" or
# "bar":
regex = ~r/foo|bar/
IO.puts("foo" =~ regex)
IO.puts("baz" =~ regex)

The output is:

true
false

 

In Elixir, Sigils support 8 different delimiters, they are:

  1. ~r/hello/
  2. ~r|hello|
  3. ~r"hello"
  4. ~r'hello'
  5. ~r(hello)
  6. ~r[hello]
  7. ~r{hello}
  8. ~r<hello>

The importance of supporting different delimiters is that different delimiters can be more suited for different sigils. E.g., using parentheses for regular expressions may be a confusing choice as they can get mixed with the parentheses inside the regex. Although, parentheses can be handy for other sigils.

Perl-compatible regexes and modifiers are supported by Elixir.

 

Strings, Char lists, and Word lists

Aside from regexes, Elixir has 3 more inbuilt sigils. They are briefly explained in this session.

Strings

The ~s sigil is used to generate strings, just like double quotes. The ~s sigil is useful, for instance, when a string contains both double and single quotes. This is shown below.

new_string = ~s(this is a string with "double" quotes, not 'single' ones)
IO.puts(new_string)

This sigil generates strings, as seen in the output below:

"this is a string with "double" quotes, not 'single' ones"

 

Char Lists

The ~c sigil is used to generate char lists, as shown below

new_char_list = ~c(this is a char list containing 'single quotes')
IO.puts(new_char_list)

The output is:

this is a char list containing 'single quotes'

 

Word Lists

The ~w sigil is used to generate lists of words (i.e. regular strings). Inside the ~w sigil, words are separated by whitespace, as shown below.

new_word_list = ~w(foo bar bat)
IO.puts(new_word_list)

The output is:

foobarbat

Also, the ~w sigil accepts the c, s, and a modifiers (that is, for char lists, strings, and atoms, respectively). They specify the data type of the elements of the resulting list:

new_atom_list = ~w(foo bar bat)a
IO.puts(new_atom_list)

The output is:

[:foo, :bar, :bat]

 

Interpolation and Escaping in Sigils

Aside from lowercase sigils, Elixir supports uppercase sigils as well, to deal with escaping characters and interpolation. As ~s and ~S will return strings, the former allows escape codes and interpolation while the latter does not. Let's consider the example below.

~s(String with escape codes x26 #{"inter" <> "polation"})
# "String with escape codes & interpolation"
~S(String without escape codes x26 without #{interpolation})
# "String without escape codes x26 without #{interpolation}"

 

Custom Sigils

We can create our own custom sigils easily. Check out the example below where we will create a sigil to convert a string to uppercase.

defmodule CustomSigil do
   def sigil_u(string, []), do: String.upcase(string)
end

import CustomSigil

IO.puts(~u/Online Elixer Tutorial/)

The output is:

ONLINE ELIXER TUTORIAL

 

SUMMARY OF THE ABOVE EXAMPLE:

Firstly, we define a module called CustomSigil and within that module, we proceeded by creating a function called sigil_u. because there was no existing ~u sigil in the existing sigil space, and we will use it. The _u indicates that we wish to use u as the character after the tilde. Note that the function definition must take two arguments, an input, and a list as well.