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.