CLI
En este capítulo se creará una pequeña aplicación de línea de comandos
para aprender lo básico de Elixir y mix.
Paso 1: Crear el Proyecto
Vamos a crear el proyecto utilizando mix new y luego hacer ls.
$ mix new stoic_cli
$ cd stoic_cli
$ ls stoic_cli
Debería mostrar algo similar a lo siguiente
$ mix new stoic_cli
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating lib
* creating lib/stoic_cli.ex
* creating test
* creating test/test_helper.exs
* creating test/stoic_cli_test.exs
Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:
cd stoic_cli
mix test
Run "mix help" for more commands
$ cd stoic_cli
$ ls
README.md lib mix.exs test
Paso 2: Crear el módulo
Vamos al archivo lib/stoic_cli.ex y eliminamos el código de fábrica.
Añadimos nuestras citas como un atributo de módulo.
defmodule StoicCli do
@quotes [
%{
quote:
"Seldom are any found unhappy from not observing what is in the minds of others. But such as observe not well the stirrings of their own souls must of necessity be unhappy.",
author: "Marcus Aurelius",
source: "Book II, Meditations"
},
%{
quote:
"Consider whence each thing came, of what it was compounded, into what it will be changed, how it will be with it when changed, and that it will suffer no evil.",
author: "Marcus Aurelius",
source: "Book XI, Meditations"
},
%{
quote:
"Accustom yourself as much as possible, when any one takes any action, to consider only: To what end is he working? But begin at home; and examine yourself first of all.",
author: "Marcus Aurelius",
source: "Book X, Meditations"
}
]
end
Paso 3: Añadir las funciones de CLI
Ahora añadiremos las funciones necesarias para ejecutar este programa como
una aplicación de consola. Por ahora la función run solamente muestra
un mensaje.
defmodule StoicCli do
@quotes [
%{
quote:
"Seldom are any found unhappy from not observing what is in the minds of others. But such as observe not well the stirrings of their own souls must of necessity be unhappy.",
author: "Marcus Aurelius",
source: "Book II, Meditations"
},
%{
quote:
"Consider whence each thing came, of what it was compounded, into what it will be changed, how it will be with it when changed, and that it will suffer no evil.",
author: "Marcus Aurelius",
source: "Book XI, Meditations"
},
%{
quote:
"Accustom yourself as much as possible, when any one takes any action, to consider only: To what end is he working? But begin at home; and examine yourself first of all.",
author: "Marcus Aurelius",
source: "Book X, Meditations"
}
]
def main(args) do
args
|> parse()
|> run()
end
defp parse(args) do
OptionParser.parse(
args,
switches: [],
aliases: []
)
end
defp run(_) do
IO.puts("""
Usage: stoic_cli
""")
end
end
Ahora añadiremos la función lista que muestra las citas.
Notar que añadimos una opción en switches y aliases.
defp parse(args) do
OptionParser.parse(
args,
switches: [list: :boolean],
aliases: [l: :list]
)
end
Además hicimos un pattern match para obtener la lista.
defp run({[list: true], _, _}) do
list()
end
Y añadimos la función para mostrar la lista
defp list() do
@quotes
|> Enum.map(fn quote ->
"#{quote.quote} --- #{quote.author} (#{quote.source})"
end)
|> Enum.join("\n")
|> IO.inspect()
end
quedando el código como sigue
defmodule StoicCli do
@quotes [
%{
quote:
"Seldom are any found unhappy from not observing what is in the minds of others. But such as observe not well the stirrings of their own souls must of necessity be unhappy.",
author: "Marcus Aurelius",
source: "Book II, Meditations"
},
%{
quote:
"Consider whence each thing came, of what it was compounded, into what it will be changed, how it will be with it when changed, and that it will suffer no evil.",
author: "Marcus Aurelius",
source: "Book XI, Meditations"
},
%{
quote:
"Accustom yourself as much as possible, when any one takes any action, to consider only: To what end is he working? But begin at home; and examine yourself first of all.",
author: "Marcus Aurelius",
source: "Book X, Meditations"
}
]
def main(args) do
args
|> parse()
|> run()
end
defp parse(args) do
OptionParser.parse(
args,
switches: [list: :boolean],
aliases: [l: :list]
)
end
defp run({[list: true], _, _}) do
list()
end
defp run(_) do
IO.puts("""
Usage: stoic_cli --list
""")
end
defp list() do
@quotes
|> Enum.map(fn quote ->
"#{quote.quote} --- #{quote.author} (#{quote.source})"
end)
|> Enum.join("\n")
|> IO.inspect()
end
end
Paso 4: Configurar Mix
Ahora necesitamos configurar el archivo mix.exs para que
utilice el módulo y llame a la función main.
defmodule StoicCli.MixProject do
use Mix.Project
def project do
[
app: :stoic_cli,
version: "0.1.0",
elixir: "~> 1.18",
start_permanent: Mix.env() == :prod,
escript: [main_module: StoicCli],
deps: deps()
]
end
# ...
Paso 5: .iex.exs
El archivo .iex.exs es opcional, pero ayuda
para precargar código al momento de hacer depuración
del código.
Primero creamos el archivo
$ touch .iex.exs
Luego añadimos un alias para que precargue
el módulo siempre.
alias StoicCli
Podremos cargar el archivo .iex.exs siempre
que lo necesitemos con
$ iex -S mix
|
También es posible cargar iex con el archivo que queremos usar directamente
|
Esto abrirá una sesión en la consola interactiva precargada con nuestro código, que nos permitirá depurarlo y ejecutar comandos y funciones.
Si un módulo es cambiado, se puede recompilar
utilizando la función r.
r(StoicCli)
Paso 6: Compilar
Ahora solo es necesario compilar el código para que genere un ejecutable.
$ mix escript.build
Y se podrá ejecutar con
$ ./stoic_cli --list
Archivos .exs
Además de la extensión de archivo .ex de Elixir, Elixir también admite archivos .exs para scripting. Elixir trata ambos tipos de archivos exactamente de la misma manera; la única diferencia está en su propósito. Los archivos .ex están pensados para ser compilados, mientras que los archivos .exs se utilizan para scripting.
Los archivos .ex se compilan en archivos BEAM, que pueden ejecutarse más tarde, mientras que los .exs se compilan en memoria y se ejecutan al instante.
Lo que es diferente es que cargar/incluir archivos .exs requiere una compilación adicional, mientras que los archivos .beam (.ex compilados) no la necesitan. Sin embargo, esa diferencia de "rendimiento" solo afecta la carga inicial.
Al momento de crear una biblioteca o aplicación en Elixir, el código fuente está escrito en archivos .ex.
Se usa .exs para comandos, scripts, archivos de configuración, pruebas o cualquier otra cosa de corta duración. Estos archivos no necesitan precompilarse y puedes ejecutarlos directamente con elixir.
$ elixir stoiccli.exs
Archivos .livemd
Livebook es una aplicación web para escribir notebooks de código interactivos y colaborativos. Los notebooks se almacenan como archivos .livemd, un subconjunto de Markdown que combina texto, código y diagramas. Los Livebooks son fáciles de leer, compartir y versionar utilizando tus herramientas habituales.
Livebook es una excelente herramienta para documentación. Muchos paquetes de Elixir usan Livebook como tutoriales, pero también puedes ejecutar Livebook directamente dentro del contexto de tu aplicación existente.