Elixir Sigils sind universelle kleine Tools zur Handhabung gängiger Datentypen. Beispiele für built-in Sigils umfassen Strings (~s
), reguläre Ausdrücke (~r)
, Datumsangaben (~D
) und Wortlisten (~w
). Aber, wie du vielleicht vermutet hast, endet die Flexibilität von Elixir hier nicht — Elixir erlaubt es uns, unsere eigenen Sigils für unsere spezifischen Bedürfnisse zu bauen. Los geht’s!
Lust auf Kreativität? Wie ihr eure eigenen Sigils bauen könnt
Konzeptuell sind Sigils Funktionen, die Parameter empfangen, wie es auch andere Funktionen tun. Die Funktionsnamen der Sigils folgen dabei einer speziellen Syntax, die du unten sehen kannst (vgl. Schritt 1). Anders als bei regulären Funktionen sind wir dabei jedoch nicht auf die üblichen Separatoren um die Funktionsparameter `()` beschränkt, sondern es stehen uns gleich acht verschiedene dieser Separatoren zur Verfügung (vgl. Schritt 2). Die Parameter eines Sigils bestehen aus einem String als Input und einer Liste an Modifikatoren (vgl. Schritt 3).
Schritt für Schritt zum eigenen Sigil
Definiere eine Funktion mit dem Namen
sigil_x
, wobei du ‚x‘ ändern kannst — es kann entweder ein einzelner Kleinbuchstabe oder eine Sequenz von Großbuchstaben sein.Such Dir aus den acht Typen einen Separator aus, der Dir gefällt:
~r(hello) ~r/hello/ ~r|hello| ~r"hello" ~r'hello' ~r[hello] ~r{hello} ~r<hello>
.
Persönliche Empfehlung: Obwohl~s/https:\/\//
und~s(https://)
dasselbe Ergebnis liefern, finde ich den zweiten Ausdruck (bei Weitem) lesbarer.
# Different syntax, same result:
iex(14)> ~s/https:\/\//
"https://"
iex(15)> ~s(https://)
"https://"
Ein Sigil nimmt zwei Parameter: einen String und eine Liste an Modifikatoren. Die Modifikatoren sind optional. Damit bekommen wir die folgende Signatur:
sigil_x(string, Modifikatoren \\ [])
.Und so sieht das dann eingebaut im Template aus: `<%= ~x(string) %>` bzw. mit Modifikatoren
`<%= ~x(string)m %>`
.
Beispiele von Custom Sigils OHNE Modifikator
Ohne einen Modifikator wird unser Sigil einfach den modifizierten Eingabestring zurückgeben. So sieht das Ganze in der Praxis aus:
Beispiel 1 ohne Modifikator
defmodule YourProject.SigilSorcery do
def sigil_UPREV(string, _modifier) do
String.upcase(string)
|> String.reverse()
end
end
Taadaa, wir haben unser erstes Custom Sigil!
Was hier passiert: Das Sigil nimmt einen String, wandelt ihn in Großbuchstaben um und reversed ihn auch gleich.
import YourProject.SigilSorcery
iex(92)> ~UPREV(hello)
"OLLEH"
Beispiel 2 ohne Modifikator
defmodule YourProject.EmojiSigil do
@emoji_map %{
"star" => "⭐",
"sun" => "🌞",
"moon" => "🌙",
"planet" => "🪐",
"rocket" => "🚀",
}
def sigil_EMO(string, _modifiers) do
String.split(string)
|> Enum.map(&replace_with_emoji/1)
|> Enum.join(" ")
end
defp replace_with_emoji(word) do
Map.get(@emoji_map, word, word)
end
end
Was hier passiert: Das Sigil nimmt einen String, splittet ihn an den Leerzeichen und ersetzt jedes einzelne Wort, für das es eine Emoji-Entsprechung findet, durch das passende Emoji. Falls das Wort keine Entsprechung hat, geben wir es zurück, ohne es durch ein Emoji zu ersetzen. Schlussendlich joinen wir die Liste wieder zu einem String.
import YourProject.EmojiSigil
iex(92)> ~EMO{star sun moon planet rocket}
"⭐ ☀️ 🌙 🪐 🚀"
iex(93)> ~EMO{hello star hello sun and moon}
"hello ⭐ hi ☀️ and see you 🌙"
Beispiele von Custom Sigils MIT Modifikator
Modifikatoren sind optional. Wenn wir sie verwenden möchten, müssen wir sie in der Funktionssignatur definieren. Modifikatoren werden als eine Liste von Strings übergeben. Wie oben schon kurz erwähnt, rufst du das Sigil folgendermaßen auf `~x(string)m`
. So sieht das Ganze in der Praxis aus:
Beispiel 1 mit Modifikator
defmodule YourProject.SigilCase do
def sigil_STR(string, 'u'), do: String.upcase(string)
def sigil_STR(string, 'l'), do: String.downcase(string)
def sigil_STR(string, 'r'), do: String.reverse(string)
end
Was hier passiert: Wir definieren drei clauses einer Funktion, von denen jede einen String und einen Modifikator nimmt. Der Modifikator ‚u‘ wandelt den String in Großbuchstaben um, ‚l‘ in Kleinbuchstaben und der Modifikator ‚r‘ reversed den String.
import YourProject.SigilCase
iex(92)> ~STR(hello)u
"HELLO"
iex(93)> ~STR(HellO)l
"hello"
iex(94)> ~STR(hello)r
"olleh"
Beispiel 2 mit Modifikator
defmodule YourProject.ZooSigil do
def sigil_ZOO(string, modifiers) do
repeat_count = String.to_integer(List.to_string(modifiers))
String.split(string)
|> Enum.map(&replace_with_animal(&1, repeat_count))
|> Enum.join(" ")
end
defp replace_with_animal(word, repeat_count) do
emoji=
case word do
"cat" -> "🐱"
"dog" -> "🐶"
"bird" -> "🐦"
_ -> word
end
String.duplicate(emoji, repeat_count)
end
end
Was hier passiert: Das Sigil nimmt einen String, splittet ihn an den Leerzeichen und ersetzt jedes einzelne Wort, für das es eine Emoji-Entsprechung findet, durch das passende Emoji. Dann geben wir das Emoji jeweils n-mal zurück, wobei n der Sigilmodifikator ist. Letztlich joinen wir die Liste wieder zu einem String.
import YourProject.ZooSigil
iex(92)> ~ZOO(cat dog bird)3
"🐱🐱🐱 🐶🐶🐶 🐦🐦🐦"
Wage es, dich der Sigilmagie zu bedienen
Sigils sind praktische kleine Werkzeuge, sie sind eine Mischung aus Effizienzoptimierung und einem Spielplatz für Deine Kreativität. Egal, ob du dich an regulären Ausdrücken austobst, mit Listen hantierst oder generell einfach nur Spaß daran hast, deine eigenen Sigils zu bauen … Sigils sind eine wertvolle Ergänzung deiner Coding Journey. Also los, setze diese Magie mit einem Lächeln ein und erlebe, wie dein Elixir-Code das Gewöhnliche hinter sich lässt und … zauberhaft wird 🧙🏼☺️.
Related stories:
Ariadne Engelbrecht
Ari stieß 2022 zu uns und arbeitet seitdem als Software Engineer bei Inspired. Egal ob Theorie oder aktives Programmieren, sie verbringt ihre Zeit am Liebsten in der IT-Welt – z.B. (als Volunteer) auf Kongressen.