Guidelines:Coding es

From openIdeas.info

Contents

Normas de estilo de desarrollo

En este documento se presentan las guías que se deben tener en cuenta cuando se escriba código para cualquiera de los proyectos de OpenIdeas. En él se incluyen políticas que deben seguirse cuando se modifica el código de otras personas, y cuando se usa el repositorio SVN.

El código debe ser limpio, consistente, mantenible y tener sentido. Esto no sólo provoca placer al trabajar con el, sino que además es un incentivo para las buenas prácticas de programación para aquellos que quieran extenderlo y modificarlo.

La importancia de escribir buen código

Gran parte del trabajo en el software libre es realizado por voluntarios; programadores que vienen y se van en cualquier momento del tiempo y que serán capaces de dedicar diferentes cantidades de tiempo tiempo a un proyecto. Muchas personas trabajan en software libre en su tiempo libre o como un pasatiempo, así, si sus responsabilidades del "mundo real" cambian, se verá reflejado en la cantidad de trabajo que dedicarán a proyectos de software libre.

El código desordenado es difícil de leer y las personas pueden perder interés si no son capaces de descifrar lo que el código intenta hacer. Además, es importante que los programadores sean capaces de entender el código rápidamente, y así poder comenzar a contribuir reparando fallos y extendiéndolo en un período breve de tiempo. El código fuente es una forma de comunicación, y así como a alguien podría no querer leer una novela con errores ortográficos y mala puntuación, los programadores deben intentar escribir buen código de tal forma que sea fácil de entender y modificar por otros.

Estilo de programación

El estilo de programación se refiere a la forma en que se da formato al código fuente. Para C, esto involucra la forma en que se ubican las llaves, se indenta el código y se utilizan los paréntesis. Lo más importante es que el código sea consistente de un programa o una biblioteca — el código con un formato desordenado no es aceptable debido a que es difícil de leer.

Cuando se escribe un nuevo programa o biblioteca, siga un estilo consistente de ubicación de llaves y de indentación. Una buena pauta es el estilo de programación del núcelo de Linux o el estilo de programación de GNU.

Estilo

Indentación

Para el código desarrollado preferimos el estilo de indentación del núcleo de Linux. Es decir, usar tabuladores de 8 espacios para indentación. Esto permite que el código sea más fácil de leer, ya que la indentación es claramente marcada. Los tabuladores de 8 espacios para indentación también ayudan al diseño de funciones que entren bien en la pantalla, lo que implica que sep pueda leer el código sin tener que desplazarse atrás y adelante para entenderlo.

Ancho del código

El ancho máximo del código es de 80 caracteres. Si alguna linea debe superar este número, se añadirán retornos de carro y se tabulará correctamente. para que quede alineado. Ejemplo:

babel_server_funcion_con_nombre_largo (parametro1_enorme,
                                       parametro2_enorme);

Espacios

Se deben añadir espacios adicionales antes de la apertura de un paréntesis y después de una coma separadora de parámetros. Ejemplo:

funcion (parametro1, otra_funcion (), parametro2);

Salto de linea ( C )

Se debe añadir un salto de linea después del tipo del parámetro devuelto en la declaración de una función. Se debe añadir otro salto de linea después del cierre de los paréntesis de los parámetros. Esto permite buscar fácilmente la definición de funciones en el código con un simple grep "^nombre_funcion" *.c. Ejemplo:

int
main (int argc, char *argv[])
{
        printf ("Hello world\n");
}

Salto de linea ( PHP )

En PHP se usa una nomenclatura diferente

function pepito ($string) {
        $string += "xxxx";
        return $string;
}

Llaves

La apertura y el cierre de llaves en los bloque también sigue un estilo. Lo mejor es verlo con un ejemplo.

if (condicion) {
        ....
} else if () {
        ....
} else {
        ....
}

Las condiciones que sólo ejecuten una instrucción pueden ponerse con o sin llaves, aunque es preferible su uso. Es decir, lo siguiente sería correcto:

if (condicion_de_salida)
        break;

Convención de nombres

Es importante seguir una buena convención de nombres para los símbolos de los programas.

Los nombres de las funciones debieran ser de la forma modulo_submodulo_operacion. Por ejemplo, babel_server_get_policy () sería un nombre correcto.

Además, se siguen las siguientes reglas:

  • Los nombres de las funciones en minúsculas, con líneas de subrayado para separar palabras, tal como: </code>babel_server_get_info ()</code>.
  • Las macros y las enumeraciones en mayúsculas, con líneas de subrayado para separar palabras, tal como: BABEL_PATH para una macro y BABEL_GENERIC_DATA para un valor enumerado.
  • Los nombres de tipos y estructuras usan una mezcla de mayúsculas y minúsculas, tal como: BabelModuleData.

Al utilizar líneas de subrayado para separar palabras hace el código esté menos apretado y facilita la edición, ya que puedes usar las secuencias de teclas que permiten navegar entre palabras más rápidamente en cualquier editor.

Consistencia entre nombres

Es importante que las variables se nombren de manera consistente. Por ejemplo, un módulo que manipula una lista puede elegir nombrar las variables que mantienen un puntero a la lista como 'l', por elegancia y simplicidad. Por supuesto, nombre muy cortos y elegantes debieran ser usados sólo para variables locales de funciones. Nunca se debe llamar a una variable global variable 'x'; se debe usar un nombre más largo que indique lo que significa.

Limpieza

El código desarrollado debe ser tan limpio como sea posible. Esto implica usar un estilo de indentación consistente y una buena convención para nombrar símbolos, como se ha indicado anteriormente. Además, también implica lo siguiente.

  • El uso correcto de la palabra reservada const. Es muy buena práctica usarlo consistentemente, así le permitirá al compilador que atrape muchos errores estúpidos. Si hay una función que retorna un puntero a un dato interno el cual se supone que el usuario no debiera liberar, deberia usar el modificador const. Este avisará al usuario si el intenta hacer alguna operación incorrecta. Por ejemplo, en la función:
const char *babel_server_get_info (const char *info);
El compilador avisará si el usuario intenta liberar la cadena devuelta. Esto ayudará para evitar muchos errores.
  • Si hay "valores mágicos" en el programa, se deben usar macros que la definan en vez de usarlos directamente en el código:
/* Amount of size */
#define BABEL_SIZE          8
#define BABEL_SIZE_SMALL    4
#define BABEL_SIZE_BIG      12
  • Si tiene una lista de valores posibles para una variable, los macros no son la mejor aproximación para ellas, sino que se mejor usar enum para darle un nombre de tipo. Además, permite disponer de nombres simbólicos en un depurador. Además, no hay que usar int para almacenar un valor enumerado, es mejor use el tipo enumerado. Esto permite al compilador atrapar los errores por tí, permitiéndole al depurador mostrar los valores apropiados y hacer obvio los valores que una variable puede tomar. A continuación un ejemplo:
/* Shadow types */
typedef enum {
	DATA_NONE,
	GENERIC_DATA,
	GENERIC_PROC,
	GENERIC_DATA_INC
} DataType;
void babel_server_set_data_type (BabelModuleData *data, DataType type);
  • No hay que escribir código ofuscado. Para clarificar una expresión, no se deben usar más paréntesis que los necesarios. Use espacios antes de los paréntesis y después de las comas y también alrededor de los operadores binarios.
  • No usar hacks en el código. En vez de escribir un hack inmantebile, es mejor reescribir el código para que quede limpio, extensible y mantenible.
  • Asegúrarse que el código compila absolutamente sin ningún aviso del compilador. Esto le ayudará a atrapar errores estúpidos.
  • Comentar el código lo justo y necesario. No coloque comentarios antes de cada función para decir que hace. No diga como lo hace a menos que sea absolutamente necesario; debería ser obvio al leer el código. Si no lo fuera, entonces pueda desear reescribirlo hasta que sea fácil de entender.

Modificando el código de otros

Hay que seguir el mismo estilo de indentación usado en el código original. El código original estará una mayor cantidad que tiempo que el puedas dedicar, manteniendo las contribuciones consistentes respecto a la indentación es más importante que forzar su estilo de indentación en el código.

Aunque sus parches pueden implementar una muy funcionalidad muy llamativa, es muy molesto para el autor tener que reindentar el código antes de aplicar un parche al código principal. Así, si el código original es:

int
sum_plus_square_of_indices (int *values, int nvalues)
{
	int i, total;

	total = 0;

	for (i = 0; i < nvalues; i++)
		total += values[i] + i * i;

	return total;
}


Entonces no añadas una función así.

int sum_plus_cube_of_indices(int *values, int nvalues) {
  int i,total;

  total=0;

  for (i=0;i<nvalues;i++)
    total+=values[i]+i*i*i;

  return total;
}

En el segundo ejemplo, la indentanción y ubicación de las llaves no coincide con el código original, no hay espacios alrededor de los operadores y el código no se parecerá al original. Siga el estilo de programación del autor original del programa.

Documentando los cambios

Para nuestro desarrollos usamos el archivo ChangeLog estándar de GNU para documentar los cambios al código. Cada cambio que efectúe a un programa debe ser acompañado por una registro en el ChangeLog. Esto permite a las personas leer la historia de cambios del programa de una manera sencilla.

Nota: Si usa Emacs, puede agregar las líneas al ChangeLog presionando “C-x 4 a”.

Cada registro en el ChangeLog tiene un forma general:

2006-04-21  J. Random Hacker  <jrandom@foo.org>
 
	* bar.c (ar_function): Fixed bug where it would print "Take
	me to your leader" instead of "Hello, World".

	* foo.c (some_function): Changed the way MetaThingies are
	frobnicated.  We now use a hash table instead of a linked list to
	look MetaThingies up.
	(some_other_function): Support the MetaThingies hash table by
	feeding it when necessary

2006-04-20  Johnny Grep  <grep@foobar.com>
 
	* baz.c (ugly_function): Beautified by using a helper function.

Una recomendación personal es que este fichero se edite con el vim, pues maneja perfectamente este fichero, haciendo los saltos de linea automáticamente e indicando los errores de tabulación, por mínimo que sea.

Para ver cuales han sido los cambios realizados, antes de hacer el commit, se puede visualizar las diferencias con varios métodos. De nuevo, una recomendación personal es usar el programa meld, o esvn. También se puede hacer de forma manual, generando un fichero diff con el siguiente comando:

svn diff > diferencias.diff

Examinando el fichero diferencias.diff se pueden ver todos los cambios con el formato estándar de diff.

Enlaces

Documentation