Cuando creamos un proyecto en Elixir con Mix y exploramos sus archivos, uno de los elementos que nos encontramos es el código fuente dentro de la carpeta lib. Allí, además del código que define módulos y funciones, podemos ver líneas que no son código ejecutable, sino documentación. Esta documentación es fundamental para entender qué hace cada parte del programa, tanto para otras personas que trabajen con nuestro código como para nosotros mismos cuando volvamos a él después de un tiempo.
La documentación nos ayuda a explicar en términos humanos la intención y funcionamiento de nuestro código. Sin ella, cualquiera que quiera entender lo que hemos escrito tendrá que dedicar mucho tiempo a estudiar el código, lo que puede ser poco práctico. Por eso, es importante que desde el principio incorporemos anotaciones que faciliten esta comprensión.
Una forma básica y muy común de documentar es mediante comentarios. En Elixir, los comentarios se escriben usando el carácter almohadilla #. Todo lo que siga a esta almohadilla en la misma línea será ignorado por el compilador y servirá solo para que los humanos podamos leer anotaciones, aclaraciones o explicaciones. Podemos colocar comentarios al inicio de una línea o al final de una expresión, según convenga. Por ejemplo, si tenemos una función que devuelve un átomo :world y queremos aclarar que es un valor provisional, podemos escribir:
def hello do
:world # Devuelvo :world porque aún no tengo un valor real
end
Es importante destacar que el idioma de los comentarios puede variar según el equipo o las normas del proyecto; algunos prefieren inglés por costumbre o por razones legales, mientras que otros pueden usar el idioma que les resulte más cómodo.
Más allá de los comentarios, Elixir ofrece una forma más estructurada y potente de documentar mediante atributos de módulo, que son anotaciones especiales que el compilador reconoce. Dos de los más importantes son @moduledoc y @doc.
El atributo @moduledoc se utiliza para documentar un módulo completo. Se coloca justo encima de la definición del módulo y se le asigna una cadena de texto que describe su propósito o funcionamiento. Para cadenas largas o que incluyan saltos de línea, es común usar las cadenas multilínea con triple comilla ("""), conocidas como here strings. Por ejemplo:
defmodule Hola do
@moduledoc """
Hola es un módulo de prueba con el que estamos experimentando.
Aquí podemos explicar qué hace el módulo y cualquier detalle relevante.
"""
def hello do
:world
end
end
Por otro lado, el atributo @doc sirve para documentar funciones o macros específicas dentro del módulo. Se coloca justo encima de la función que queremos describir y también recibe una cadena de texto con la explicación. Así, cuando estemos usando herramientas o editores compatibles, podremos ver esta documentación contextualizada. Por ejemplo:
@doc """
hello es una función que saluda.
"""
def hello do
:world
end
Estas anotaciones no solo son útiles para nosotros al leer el código, sino que también pueden ser procesadas por herramientas que generan documentación automática en formatos como HTML. Por ejemplo, Visual Studio Code puede mostrar la documentación al situar el cursor sobre un módulo o función, y herramientas como xdoc permiten crear páginas web con toda la documentación extraída del código fuente.
Un detalle interesante es que la documentación en @moduledoc y @doc puede incluir markdown, lo que permite dar formato al texto, incluir listas, enlaces y otros elementos que mejoran la presentación cuando se visualiza con las herramientas adecuadas.
En la librería estándar de Elixir, por ejemplo en el módulo Kernel, podemos ver cómo se utiliza @moduledoc para ofrecer una descripción extensa y detallada del módulo, con formato markdown para facilitar la lectura.
En resumen, documentar nuestro código en Elixir implica combinar comentarios para anotaciones rápidas y explicativas dentro del código, con atributos de módulo como @moduledoc y @doc para crear documentación formal y estructurada que pueda ser procesada y mostrada por herramientas especializadas. Esto facilita la colaboración, el mantenimiento y la comprensión del código a largo plazo.