Elixir Sigils - Text Structure Creation

Explore Elixir Sigils for efficient text structure creation. Learn how to use built-in and custom sigils for strings, charlists, lists of words, and regex with interpolation.

Elixir Sigils

Understanding Elixir Sigils for Text Structures

Elixir sigils provide a powerful and concise way to create specific data structures from text. They offer a syntactic sugar that simplifies common text processing tasks. The general form of a sigil is ~type| content |m, where type indicates the kind of structure to be created, and content is the text to be processed. Sigils can be delimited by various characters such as {}, [], (), //, ||, "", or '', offering flexibility in their usage.

Built-in Elixir Sigils

Elixir comes with several built-in sigils designed for common data types:

Creates With Interpolation Without Interpolation
String s S
Charlist c C
List of words w W
Regular Expression r R

Here are some examples demonstrating the usage of these built-in sigils:

> a = "Yay!"
> ~s|Quotes #{a} 'used' "willy nilly.|   # "Quotes Yay! 'used' \"willy nilly.\""
> ~S{Not "interpolated" #{a}}            # "Not \"interpolated\" \#{a}"
> ~c[charlist "with" 'quotes' #{a}]      # 'charlist "with" \'quotes\' Yay!'
> ~w/a list of words #{a}/               # ["a", "list", "of", "words", "Yay!"]
> ~W"a list of words #{a}"               # ["a", "list", "of", "words", "\#{a}"]

Modifying Word List Sigils

The ~w (with interpolation) and ~W (without interpolation) sigils can be further modified to specify the output type for each word. You can append a for atoms, c for charlists, or s for strings.

> ~w|alpha bravo charlie|a   # [:alpha, :bravo, :charlie]
> ~w|alpha bravo charlie|c   # ['alpha', 'bravo', 'charlie']
> ~w|alpha bravo charlie|s   # ["alpha", "bravo", "charlie"]

Defining Custom Elixir Sigils

Beyond the built-in sigils, Elixir allows developers to define their own custom sigils, extending the language's expressiveness. This is achieved by defining a module with functions named sigil_TYPE, where TYPE is the character used for the sigil.

For instance, you can create a sigil that parses numbers and performs operations:

defmodule MySigil do
  # Sigil for integers, optionally doubling them with 'd' option
  def sigil_i(string, 'd') do
    for num <- String.split(string), do: String.to_integer(num) * 2
  end
  # Default sigil for integers
  def sigil_i(string, _opts) do
    for num <- String.split(string), do: String.to_integer(num)
  end
end
> import MySigil
> ~i|1 2 3 4 5|   # [1, 2, 3, 4, 5]
> ~i|1 2 3 4 5|d  # [2, 4, 6, 8, 10]

Custom sigils are particularly useful for domain-specific languages or complex parsing tasks, making your Elixir code more readable and maintainable.