Cómo documentar el código

Introducción

A continuación explicaré una metodología para documentar código fuente, que aunque en principio supondré que es para C++, esto es lógicamente extensible a cualquier otro lenguaje (JAVA, C, PHP, …), ya sea orientado a objetos o no.

Los objetivos finales de la documentación dentro del código fuente serán:

  • Que el código quede documentado de modo que los que lean, mantengan, reparen, etc el código lo entiendan.
  • Poder extraer de manera automatizada la documentación, en un formato leible, como HTML, PDF, CHM, etc.
  • Que documentar sea una tarea fácil, y que no suponga un sobreesfuerzo, más allá de lo extrictamente necesario.

Ejemplo de código fuente sin documentar:

int CalcularReintentos (const char *opcion,
                        bool similitud = true);

El problema de este método (o función) es que el programador que lo quiera invocar, va a tener que irse a la implementación del mismo (en el correspondiente CPP), y leer todo el código del mismo, hasta entender su contenido, lo cual le llevará (dependiendo de la implementación) un buen rato, siendo este tiempo superior al que habría tardado en leer la documentación (si esta existiera) del método en cuestión.

Este es el mismo ejemplo, pero documentado:

/** Este método calcula el número de reintentos de una
    determinada opción.
    @param opcion Cadena de texto con la opción a parsear
           para extraer el número de reintentos. La sintaxis es
           la siguiente: "reintentos:XXX", donde XXX será una
           cadena de texto que se interpretará como un
           número (valor retornado).
    @param similitud Flag que si vale true (valor por defecto)
           hará que el método no distinga las letras mayúsculas
           a la hora de intentar parsear la sintaxis, de modo
           que "reintentos:XXX" sea igual de válido que
           "ReinteNTos:XXX".
    @return Devuelve el número de reintentos o -1 en caso
            de error. */
int CalcularReintentos (const char *opcion,
                        bool similitud = true);

Bastante mejor, ¿no?. Bueno vayamos a la chicha

Sintáxis básica para documentación

La sintáxis es realmente sencilla (de echo con el ejemplo anterior, ya habréis aprendido casi la mitad de las reglas 😉 ):

  1. Todo comentario debe empezar por /**, y terminar en */.
  2. Los comentarios (con /** ... */) deben situarse en la línea inmediatamente superior a lo que queremos documentar (a veces la gente pone comentarios a la derecha de un atributo, lo cual documentaría el siguiente atributo, y no el de la línea actual).
  3. Lo primero dentro de un comentario debe ser la descripción textual de lo que estamos documentando, luego (dependiendo de lo que estemos documentando (un atributo, un método, una clase, …)) pueden venir los siguientes campos:
    • @param xxx yyy Esto documenta un parámetro (xxx) con una descripción (yyy).
    • @return yyy Documenta el valor retornado (yyy) por el método (o función).

Con estas sencillas reglas ya podemos documentar casi cualquier cosa, por ejemplo una clase Fecha:

/** Esta clase da soporte al uso de fechas. */
class Fecha
{
 
// Atributos privados.
private:
 
    /** Número de milisegundos desde el año cero. */
    i64 fecha;
 
// Métodos públicos.
public:
 
    /** Constructor. */
    Fecha ();
    /** Constructor de copia.
        @param objeto Objeto a copiar. */
    Fecha (const Fecha &objeto);
    /** Destructor. */
    virtual ~Fecha ();
 
    /** Establece la fecha a partir de sus subelementos.
        @param anyos Años a copiar.
        @param meses Meses a copiar (0 por defecto).
        @param dias Dias a copiar (0 por defecto).
        @param horas Horas a copiar (0 por defecto).
        @param minutos Minutos a copiar (0 por defecto).
        @param segundos Segundos a copiar (0 por defecto).
        @param milisegundos Milisegundos a copiar (0 por defecto).
        @return Devuelve una referencia a este objeto. */
    Fecha &Set (i32 anyos,
                i32 meses = 0,
                i32 dias = 0,
                i32 horas = 0,
                i32 minutos = 0,
                i32 segundos = 0,
                i32 milisegundos = 0);
 
    /** Devuelve una cadena de texto con la descripción
        de la fecha.
        @return Devuelve una cadena de texto con la
                descripción de la fecha. */
    const i8 *GetDescripcion () const;
 
};

Tratamiento automático

Que la documentación sea hecha mediante comandos con una sintáxis dada, no es casualidad, dado que uno de los objetivos, es que no sólo humanos entiendan unívocamente que significa cada comentario, sino que herramientas de extracción automatizada de documentación también sean capaces.

Una herramienta que siempre me ha dado buen resultado es Doxygen, para usarla tenéis que descargarla de la web oficial (o si usais Linux bajarla del repositorio de turno, dado que esta herramienta viene en las distribuciones oficiales desde hace años) e instalarla.

Doxygen permite generar proyectos donde indicar las diferentes opciones para la documentación a generar (viene con un Wizard que facilita mucho esta tarea, y también de una excelente y completísima documentación), de modo que no lo trataré aqui.

La idea es indicar a la herramienta que ficheros (o directorios) queremos que analice en busca de documentación, y el generará unas páginas HTML (también exporta a PDF, MAN, LaTeX, CHM, …) con dicha documentación. Un ejemplo del resultado de esta documentación lo podéis encontrar en la documentación de Apache Portable Runtime o en la página de documentación de esta misma web.

Sintáxis adicional

Además de los comandos vistos (@param, @return), hay otros comandos que pueden resultar interesantes:

  • @note xxx Este comando sirver para poner notas (xxx) o comentarios.
  • @warning Indica alertas (xxx) o posibles problemas, especialmente útil cuando documentamos un método que dado un parámetro inválido, puede causar un error grave.
  • @author xxx Este comando indicará quien (xxx) es el autor.
  • @date xxx Señala fechas, donde xxx suele ser una fecha seguida de una descripción de que se ha hecho en dicha fecha, con esto podemos hacer listas de cambios, poniendo sucesivas llamadas a este comando.

4 comentarios

  1. Jose dice: Responder

    ¿Cómo haces para agregar codigo a tu sitio?
    ¿Es alguna extensión del CMS , o tu los agregas manualmente con CSS y HTML?

    1. Hola Jose.
      Esta web está escrita con WordPress, el cual tiene plugins como el WP-Syntax que permiten escribir código fácilmente sin nada especial.

  2. Hola Daniel,

    No era mi idea hacer una comparativa de herramientas en este post, aunque la he hecho en el pasado por motivos profesionales, y el ganador fue doxygen. De todas formas eso fue hace tiempo, de modo que no tiene porque seguir siendo así ahora… De todos modos, para mi sigue siendo una GRAN HERRAMIENTA.

    Toda la información la tienes en el post, y como ya he dicho en anteriores posts, nunca envío emails con respuestas, dado que el conocimiento no se extendería.

    Si quieres enterarte instantáneamente de los comentarios, tienes dos opciones:
    – Subscribirte al RSS de comentarios.
    – Registrarte en la web, y te llegarán correos con los nuevos comentarios.

  3. Hola, quisiera saber que herramientas para documentar cósido son usadas con mayor frecuencia y poseen una licencia gratuita…. ah y si pueden me envian la respuesta al cooreo electronico… muchas gracias por todo…. y espero una respuesta, por favor!!!

    Esta muy interesante el “foro”

Deja un comentario