Do you want to pick up from where you left of?
Take me there

Documentación

Documentando código Elixir.

Anotación

Cuánto documentamos y qué hace que la documentación de calidad siga siendo un tema polémico dentro del mundo de la programación. Sin embargo, todos podemos estar de acuerdo que la documentación es importante para nosotros y para aquellos que trabajan con nuestro código.

Elixir trata la documentación como ciudadanos de primera clase, ofreciendo varias funciones para acceder y generar documentación para tus proyectos. El núcleo de Elixir nos provee con diferentes atributos para documentar el código. Vamos a ver 3 formas:

Documentación en linea

Probablemente la forma más simple de comentar tu código es con comentarios en linea. Similar a Ruby o Python, el comentario en linea de Elixir está denotado con #, frecuentemente conocido como almohadilla o de alguna otra forma de acuerdo de donde seas.

Toma este script de Elixir (greeting.exs):

# Outputs 'Hello, chum.' to the console.
IO.puts "Hello, " <> "chum."

Elixir, cuando ejecuta este script ignorará todo desde # hasta el final de la linea, tratándolo como datos sin uso. Esto puede no agregar valor a la operación o rendimiento del script, sin embargo cuando no es obvio que está pasando, un programador debería saberlo leyendo tu comentario. ¡Se consciente de no abusar del comentario en línea! Ensuciar un código puede volverse una pesadilla para algunos. Es mejor usarlo con moderación.

Documentando Módulos

El anotador @moduledoc permite agregar documentación al nivel de módulo. Esto típicamente se sitúa bajo la declaración defmodule al inicio del archivo. El ejemplo a continuación muestra un comentario de una línea dentro del decorador @moduledoc.

defmodule Greeter do
  @moduledoc """
  Provides a function `hello/1` to greet a human
  """

  def hello(name) do
    "Hello, " <> name
  end
end

Nosotros (u otros) podemos acceder a esta documentación usando la función de ayuda h dentro de IEx.

iex> c("greeter.ex", ".")
[Greeter]

iex> h Greeter

                Greeter

Provides a function hello/1 to greet a human

Documentando Funciones

Al igual que Elixir nos da la habilidad para documentar a nivel de módulo, también habilita similares anotaciones para documentar funciones. El anotador @doc permite agregar documentación a nivel de función. El anotador @doc se sitúa justo sobre la función que está comentando.

defmodule Greeter do
  @moduledoc """
  ...
  """

  @doc """
  Prints a hello message

  ## Parameters

    - name: String that represents the name of the person.

  ## Examples

      iex> Greeter.hello("Sean")
      "Hello, Sean"

      iex> Greeter.hello("pete")
      "Hello, pete"

  """
  @spec hello(String.t()) :: String.t()
  def hello(name) do
    "Hello, " <> name
  end
end

Si entramos en IEx otra vez y usamos el comando de ayuda (h) con la función precedida por el nombre del módulo, veremos lo siguiente:

iex> c("greeter.ex")
[Greeter]

iex> h Greeter.hello

                def hello(name)

Prints a hello message

Parameters

   name: String that represents the name of the person.

Examples

    iex> Greeter.hello("Sean")
    "Hello, Sean"

    iex> Greeter.hello("pete")
    "Hello, pete"

iex>

¿Notas como puedes usar marcado dentro de la documentación y la terminal lo renderizará? Además de ser realmente genial y una adición novedosa al vasto ecosistema de Elixir, se vuelve mucho más interesante cuando vemos que ExDoc genera documentación en HTML sobre la marcha.

Nota: la anotación @spec es usada para análisis estático del código. Para aprender mas acerca de eso, revisa la lección Especificaciones y tipos.

ExDoc

ExDoc es un proyecto oficial de Elixir que puede ser encontrado en GitHub. Produce HTML (HyperText Markup Language) y documentación en línea para proyectos Elixir. Primero vamos a crear un proyecto Mix para nuestra aplicación:

$ mix new greet_everyone

* creating README.md
* creating .gitignore
* creating .formatter.exs
* creating mix.exs
* creating lib
* creating lib/greet_everyone.ex
* creating test
* creating test/test_helper.exs
* creating test/greet_everyone_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd greet_everyone
    mix test

Run "mix help" for more commands.

$ cd greet_everyone

Ahora copia y pega el código de la lección del anotador @doc en un archivo llamado lib/greeter.ex y asegúrate de que todo aun está funcionando desde la línea de comandos. Ahora que estamos trabajando dentro de un proyecto Mix necesitamos empezar IEx de una forma un poco diferente usando el comando iex -S mix:

iex> h Greeter.hello

                def hello(name)

Prints a hello message

Parameters

  • name: String that represents the name of the person.

Examples

    iex> Greeter.hello("Sean")
    "Hello, Sean"

    iex> Greeter.hello("pete")
    "Hello, pete"

Instalando

Asumiendo que todo esta bien vamos a ver la salida siguiente, ahora estamos listos para configurar ExDoc. En el archivo mix.exs, agrega las dos dependencias requeridas: :earmark y :ex_doc.

  def deps do
    [{:earmark, "~> 1.2", only: :dev},
    {:ex_doc, "~> 0.19", only: :dev}]
  end

Especificamos el par llave-valor only: :dev porque no queremos descargar y compilar estas dependencias en un entorno de producción. Pero ¿Por qué Earmark? Earmark es un parser Markdown para el lenguaje de programación Elixir el cual ExDoc utiliza para convertir nuestra documentación dentro de @moduledoc y @doc en hermoso HTML.

Vale la pena señalar en este punto que no estas forzado a usar Earmark. Puedes cambiar la herramienta de marcado a otros como Pandoc, Hoedown, o Cmark; sin embargo vas a necesitar hacer un poco mas de configuración la cual puedes leer aquí. Para este tutorial, seguiremos con Earmark.

Generando documentación

Desde la linea de comandos ejecuta los siguientes comandos:

$ mix deps.get # gets ExDoc + Earmark.
$ mix docs # makes the documentation.

Docs successfully generated.
View them at "doc/index.html".

Si todo fue de acuerdo al plan, deberías ver un mensaje similar al mensaje de salida del anterior ejemplo. Ahora vamos a ver dentro de nuestro proyecto Mix y deberíamos ver que hay otro directorio llamado docs/. Dentro está nuestra documentación generada. Si visitamos la página indice(index.html) en nuestro navegador deberíamos ver lo siguiente:

ExDoc Screenshot 1

Podemos ver que Earmark ha renderizado nuestro Markdown y ExDoc y ahora lo muestra en un formato útil.

ExDoc Screenshot 2

Ahora podemos publicar esto en GitHub, a nuestro propio sitio web, o mas comunmente a HexDocs.

Mejores Prácticas

La documentación agregada debería ser agregada dentro de las directrices de mejores prácticas del lenguaje. Ya que Elixir es un lenguaje bastante joven muchos estándares aun esta siendo descubiertos conforme el ecosistema crece. La comunidad, sin embargo, intentó establecer las mejores prácticas. Para leer acerca de estas mejores prácticas puedes revisar The Elixir Style Guide.

defmodule Greeter do
  @moduledoc """
  This is good documentation.
  """

end
defmodule Greeter do
  @moduledoc false

end
defmodule Greeter do
  @moduledoc """
  ...

  This module also has a `hello/1` function.
  """

  def hello(name) do
    IO.puts("Hello, " <> name)
  end
end
defmodule Greeter do
  @moduledoc """
  ...

  This module also has a `hello/1` function.
  """

  alias Goodbye.bye_bye
  # and so on...

  def hello(name) do
    IO.puts("Hello, " <> name)
  end
end
defmodule Greeter do
  @moduledoc """
  ...
  """

  @doc """
  Prints a hello message

  ## Parameters

    - name: String that represents the name of the person.

  ## Examples

      iex> Greeter.hello("Sean")
      "Hello, Sean"

      iex> Greeter.hello("pete")
      "Hello, pete"

  """
  @spec hello(String.t()) :: String.t()
  def hello(name) do
    "Hello, " <> name
  end
end
¿Encontraste un error o quieres contribuir a la lección? ¡Edita esta lección en GitHub!