Sigils
Elixir proporciona una sintaxis alternativa para representar y trabajar con literales. Un Sigils comenzará con una tilde
~ seguido de un carácter. El núcleo Elixir nos proporciona algunos Sigils integrados, sin embargo, es posible crear el nuestros propios Sigils cuando necesitamos extender el lenguaje.
Los Sigils disponibles son:
~ C Genera una lista de caracteres
sin escape ni interpolación
~ c Genera una lista de caracteres
con escape e interpolación
~ R Genera una expresión regular
sin escape ni interpolación
~ r Genera una expresión regular
con escape e interpolación
~ S Genera una cadena
sin escape ni interpolación
~ s Genera una cadena
con escape e interpolación
~ W Genera una lista de palabras
sin escape ni interpolación
~ w Genera una lista de palabras
con escape e interpolación
~ N genera una estructura NaiveDateTime
Una lista de delimitadores incluye:
<...> Un par de signos menor/mayor
{...} Un par de llaves
[...] Un par de corchetes
(...) Un par de paréntesis
| ... | Un par de barras verticales
/.../ Un par de barras diagonales
"..." Un par de comillas dobles
'...' Un par de comillas simples
Lista de caracteres
~c y ~C generan una lista de caracteres:
iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'
iex> ~C/2 + 7 = #{2 + 7}/
'2 + 7 = \#{2 + 7}'
Podemos ver que la minúscula ~c interpola el cálculo, mientras que la mayúscula ~C no. Veremos que esta propiedad de mayúsculas o minúsculas es común en todos los sigils.
Expresiones regulares
~ r y ~ R se usan para representar expresiones regulares. Los podemos crear justo en el momento de utilizarlo o para usar dentro de las funciones de Regex. Por ejemplo:
iex> re = ~r/elixir/
~r/elixir/
iex> "Elixir" =~ re
false
iex> "elixir" =~ re
true
Podemos ver que en la primera prueba de igualdad, no coincide con la expresión regular. Esto se debe a que está en mayúscula. Debido a que Elixir admite expresiones regulares compatibles con Perl (PCRE), podemos agregar i al final para desactivar la distinción entre mayúsculas y minúsculas.
iex> re = ~r/elixir/i
~r/elixir/i
iex> "Elixir" =~ re
true
iex> "elixir" =~ re
true
Además, Elixir proporciona la API de expresiones regulares que está construida sobre la biblioteca de expresiones regulares de Erlang. Es decir que podemos utilizarlos en funciones, veamos un ejemplo:
iex> string = "100_000_000"
"100_000_000"
iex> Regex.split(~r/_/, string)
["100", "000", "000"]
String
~s y ~S se utilizan para generar cadenas. Por ejemplo:
iex> ~s/the cat in the hat on the mat/
"the cat in the hat on the mat"
iex> ~S/the cat in the hat on the mat/
"the cat in the hat on the mat"
¿Cuál es la diferencia? La diferencia es similar a los otros sigils que vimos. La respuesta es la interpolación y el uso de secuencias de escape. Si tomamos otro ejemplo:
iex> ~s/welcome to elixir #{String.downcase "school"}/
"welcome to elixir school"
iex> ~S/welcome to elixir #{String.downcase "school"}/
"welcome to elixir \#{String.downcase \"school\"}"
Word List
La lista de palabras puede ser útil de vez en cuando. Puede ahorrar tiempo, pulsaciones de teclas y posiblemente reducir la complejidad dentro del código. Por ejemplo:
iex> ~w/i love elixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love elixir school/
["i", "love", "elixir", "school"]
Podemos ver que el delimitador es espacio en blanco. Sin embargo, no hay diferencia entre estos dos ejemplos. De nuevo, la diferencia viene con las secuencias de interpolación y escape. Por ejemplo:
iex> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]
iex> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]
NaiveDateTime
Un NaiveDateTime puede ser útil para crear rápidamente una estructura para representar un DateTime sin una zona horaria.
En su mayor parte, deberíamos evitar crear una estructura NaiveDateTime directamente. Sin embargo, es muy útil para la coincidencia de patrones. Por ejemplo:
iex> NaiveDateTime.from_iso8601("2015-01-23 23:50:07") == {:ok, ~N[2015-01-23 23:50:07]}
Crear un Sigils
Uno de los objetivos de Elixir es ser un lenguaje de programación extensible. No debería sorprender entonces que pueda crear fácilmente sus propios sigils personalizados. En este ejemplo, crearemos un sigils para convertir una cadena en mayúscula. Como ya existe una función para esto en Elixir Core (String.upcase/1), envolveremos nuestro sigils alrededor de esa función.
iex> defmodule MySigils do
...> def sigil_u(string, []), do: String.upcase(string)
...> end
iex> import MySigils
nil
iex> ~u/elixir school/
ELIXIR SCHOOL
Primero definimos un módulo llamado MySigils y dentro de ese módulo, creamos una función llamada sigil_u. Como no existe un sigilo en el espacio de sigilo existente, lo usaremos. El _u indica que deseamos usar u como el carácter después de ~ . La definición de la función debe tomar dos argumentos, una entrada y una lista.