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.
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:
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.
Aside from regexes, Elixir has 3 more inbuilt sigils. They are briefly explained in this session.
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"
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'
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]
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}"
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
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.