doc/GaladrielCodingStyle.txt
changeset 0 04114bce8fd0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/GaladrielCodingStyle.txt	Thu May 18 23:05:01 2006 +0200
@@ -0,0 +1,303 @@
+                        Galadriel coding style
+
+                        Lluís Batlle i Rossell
+                     viric@vicerveza.homeunix.net
+
+		     Iniciat el 11/08/2003
+
+
+Aquest és un petit document que descriu l'estil d'escriptura de codi pel
+projecte Galadriel. L'estil d'escriptura és molt personal, i no s'han de forçar
+aquestes idees sobre ningú, però ja que és una cosa que hem de mantenir entre
+tots, seria bo que l'estil no ens dificultés aquesta feina. Així que, si més no,
+tingueu en compte els punts que aquí es mencionen.
+
+Aquest document no està ni revisat ni acabat. En alguns llocs hi ha comentaris
+de la forma (MAJUSCULES ?!), que significa que no sé què posar-hi, i algú de
+vosaltres segur que ho sabrà millor i abans que jo.
+
+Aquest document també està molt influenciat per la guia de Linus Torvalds:
+"Linux kernel coding style". El google us donarà la referència a aquest escrit.
+
+Espero comentaris ben aviat...
+
+
+                           1. Indentació (sagnat)
+
+Els tabuladors estan pensats per ser d'una longitud de 8 caràcters. Si volem
+respectar a la resta de món, aquest és l'esquema que hauriem de seguir. Però
+segur que s'aixecarà protestant molta gent si pretenem tabulacions d'aquesta
+mida. Això és perquè molta gent troba excessius 8 caràcters per a indentar; bé,
+indentar serveix per diferenciar quan comença i acaba un bloc de control, així
+que si fem indentacions grans diferenciarem molt més aquests blocs, sobretot
+quan alguns de nosaltres portem més de 15 hores davant de codi.
+
+Molts direu, tot i això, que 8 caràcters és una indentació massa gran, i que
+mouen el codi massa cap a la dreta... bé, tal com diu el senyor Torvalds, "if
+you need more than 3 levels of indentation, you're screwed anyway, and should
+fix your program". Això vol dir que utilitzar 8 caràcters també ens dóna una
+idea de quant bo és el nostre codi.
+
+Fer servir tabuladors de menys de 8 caràcters també porta problemes entre
+editors... sobretot per discernir quan s'indenta amb tabuladors o bé amb espais.
+
+De tota manera, podem justificar l'ús d'indentacions més petites perquè no és el
+mateix escriure en C++ que amb C; sembla una excusa, però és amb l'únic que ens
+podem recolzar. Queda doncs establert, tal com es va decidir a l'explicació d'en
+Shadow el dissabte, que s'utilitzarà indentació amb espais de 3 caràcters.
+
+
+                          2. Ample de pantalla
+
+Molts utilitzem GUIs per escriure el nostre codi, i el fet d'estar allunyat de
+l'antic mode de 80x25, tenir resolucions més grans i fonts més petites ens ha
+permès arribar a pantalles de 170x60. De tota manera, tot i que ens pensem que
+la majoria de gent ja utilitza resolucions superiors a 1024x768, no és bo
+imposar als programadors la nostra manera d'escriure codi. Encara són molts els
+que programen en 80x25, més que res perquè són les dimensions dels terminals més
+comuns. Són amb la que els terminals VT servien les lletres més grans
+(ideals per programadors cansats), les que ens dóna la BIOS abans de l'arrencada
+del sistema, i la de la majoria d'emuladors de terminal de X. A més a més,
+facilita molt el tenir diferents porcions de codi a la pantalla alhora. I donat
+que suposem que tothom disposa de monitors de diagonal poc superior a 14", les
+mides de caràcter no són massa petites per passar llargues hores davant la
+pantalla.
+
+
+                             3. Claus {}
+
+Un altre assumpte que sol portar confusions i incomoditats només perquè hi ha
+diferents estils d'escriptura de codi és la col·locació de les claus d'inici i
+fi de bloc. Seguint les indicacions de Kernighan i Ritchie, l'estil preferit és
+el de posar la clau d'obertura a final de línia, i la de tancament indentada a
+la mateixa columna que el que ha iniciat el bloc:
+
+   if (x == 1) {
+      printf("Hola");
+   }
+
+Tot i això hi ha un cas especial, les funcions. Tenen la clau d'obertura a
+l'inici de la següent línia, així:
+
+   int funcio(int x)
+   {
+      return 2*x;
+   }
+
+A molts no ens agrada aquesta aquesta inconsistència, però té una justificació:
+les funcions no es poden aniuar. El fet d'utilitzar sempre l'obertura de clau a
+la pròxima línia també fa que en aquesta línia no hi hagi res més escrit mai, i
+porta a problemes de lectura, com en els casos:
+	
+	do
+	{
+		printf( "%i\n", i );
+	}
+	while( i < 10 );
+
+o bé,
+
+	if( i > 10 )
+	{
+		printf( "i gran\n" );
+	}
+	else
+	{
+		printf( "i petita\n" );
+	}
+
+coses que evidentment queden molt més clares així:
+
+	do {
+		printf( "%i\n", i );
+	} while( i < 10 );
+
+o bé
+
+	if( i > 10 ) {
+		printf( "i gran\n" );
+	} else {
+		printf( "i petita\n" );
+	}
+
+El més important és que no quedin línies buides, ja que hem de pensar en les 25
+línies, a part de les 80 columnes. Al deixar menys línies buides permet
+reaprofitar aquestes línies de pantalla que no perdem per a afegir comentaris.
+
+
+                        4. Espaiat d'expressions
+
+Les expressions poden arribar a ser molt críptiques si no estan ben espaiades (o
+gens). Per tant, adoptarem la regla general de posar un espai entre cada valor
+(immediat o variable) i el seu operador binari, i no posar cap espai entre un
+operador unari i el valor a què afecta. Si les variables no fan servir caràcters
+més enllà dels alfanumèrics, això no hauria de suposar cap problema de lectura.
+
+El pas de paràmetres en una crida a una funció, així com a la seva definició, es
+farà enganxant el parèntesi d'obertura al nom de la funció, i els paràmetres el
+seguiran començant amb un espai de separació entre aquest parèntesi i el primer,
+i els següents aniran succeint com si d'un text redactat es tractés. Entre
+l'últim paràmetre i el parèntesi de tancament hi haurà, com en l'obertura, un
+espai de separació.
+
+En el cas de no haver-hi paràmetres, podem utilitzar () enganxat al nom de la
+funció.
+
+
+                       5. Definició de variables
+
+Alguns caràcters especials defineixen variables com a punters o referències als
+tipus de dades amb què les declarem. Considerarem que aquests caràcters no són
+operadors unaris, i són una dada més alhora de definir el paràmetre. Per tant,
+s'escriuran un espai després del tipus de dades a què apunten o referencien, i
+separats tans espais com calgui del nom de la variable (en el cas que alineem
+definicions). Això s'aplicarà tan al cos de les funcions com a la declaració
+dels seus paràmetres o valors de retorn.
+
+
+                            6. Nomenclatura
+
+Queda clar que totes les funcions i variables han de tenir noms clarament
+descriptius. Això sol implicar que aquests noms estiguin composats de més d'una
+paraula. Seguint l'estil dels de QT, utilitzarem la tècnica de que les paraules
+que composen el nom d'una class comencen totes amb majúscula (Amb una G
+majúscula de Galadriel a davant en el codi del kernel). Els mètodes
+s'escriuran igual que les classes, però amb la lletra de la primera paraula en
+minúscula. Les variables, igual que els mètodes (moltes vegades, en programació
+a objectes, no sabem si referenciem a mètodes o a variables. Això ha de
+mantenir-se transparent).
+
+	class Tree
+	{
+		int * firstLeaf;
+
+	public:
+		void addLeaf();
+	};
+
+En el cas de parlar de comptadors o altres estructures de codi en què l'ús de
+les variables queda molt clar, podem utilitzar variables d'una sola lletra (i,
+j, k, ...), preferiblement comptant per la i i sempre en minúscula.
+
+En implementar algoritmes matemàtics també podem utilitzar variables d'una sola
+lletra sempre i quan hi hagi un extens comentari amb el codi expressat
+matemàticament.
+
+
+                         7. Classes i estructures
+
+Entenem l'idea de Classe amb C++ com a una definició d'objectes que conté
+variables i -indispensablement- mètodes. Si ens trobem davant del típic ús de C
+d'una 'struct', ho declararem com a 'struct'. Queda despreciada l'estructura:
+
+	class MyClass
+	{
+	public:
+		int   a;
+		int   b;
+		int * c;
+	}
+
+Evidentment, només utilitzarem aquest concepte d'estructura si la idea d'una
+"classe amb els seus mètodes" fa complicat l'ús d'aquestes dades. També hem de
+preveure si farà o no falta una futura encapsulació; en aquest cas declararem
+una classe amb mètodes senzills.
+
+El tipus de definicions (public, protected o private, així com slots i signals)
+es faran al nivell d'indentació de la funció, ja que la indentació serveix per
+indicar 'blocs', i això és el que volem aquí. Podem utilitzar vàris entorns de
+public, protected o private per afegir claredat a la definició de la classe,
+utilitzant-los de separadors en les definicions de membres.
+
+Quan declarem una classe també espaiarem el nom de la classe, els
+dobles dos punts i el nom del mètode. Igualment amb l'herència en la definició
+de classes i en la crida a constructors de la mare.
+
+
+                           8. Mètodes senzills
+
+És fàcil trobar-nos amb mètodes (i sobretot constructors) que simplement
+assignen els valors dels paràmetres a variables privades de la classe. Per
+evitar codi redundant, utilitzarem el mètode ja disponible en C i que s'ha
+arrossegat fins a la crida de constructors de classes mare. Així que
+utilitzarem:
+
+	void MyClass :: Constructor( int _myVar )
+		: mother( _myVar ), classVar( _myVar ), 
+	{
+		//.... codi (si cal!)....
+	}
+
+Aquestes declaracions es poden fer fins i tot (preferiblement) -inline- dins
+la definició de la classe.
+
+La nomenclatura dels paràmetres de mètodes d'aquest tipus es farà utilitzant
+exactament el mateix nom que la variable interna, fet amb què s'evitarà
+utilitzar caràcters no alfanumèrics en la definició de variables (o altres
+invents) i s'aconseguirà l'ús de l'estructura anterior. En qualsevol altre cas,
+s'utilitzaran recursos de 'namespace' per diferenciarles (que és el que realment
+fem mentalment quan llegim codi que no compleix això).
+
+
+                                 9. Funcions
+
+Igual que amb l'indentació, hem d'evitar les funcions amb molts de paràmetres,
+ja que la definició i les crides ocuparien moltes columnes.
+Això significa que la funció és molt complexa; s'ha de derivar en funcions més
+senzilles. Qualsevol ha de poder entendre una funció pel seu nom, i qualsevol
+funció ha de ser prou senzilla com per ser reutilitzada al màxim. En casos en
+què necessitem un codi molt ràpid, podem demanar al compilador que ens posi les
+funcions 'inline'.
+
+Una funció ha de ser prou senzilla com per tenir poques variables locals. Masses
+variables locals indiquen que estem fent una funció que fa masses coses. Hem de
+tenir en compte que una funció és una cosa que el nostre cap ha de poder
+entendre al 100% en un mateix instant; no val a haver d'entendre el codi d'una
+funció per parts. El límit de variables locals el posa el nostre cervell.
+A més, sempre ens ho hem d'imaginar amb la perspectiva amb què veiem un codi fet
+fa dues setmanes, no amb la del moment d'escriure'l.
+
+
+                           10. Comentaris
+
+És molt bo que hi hi hagi comentaris en el que escrivim, sobretot per
+ajudar-nos a entendre què fa un tall de codi. Això és molt important si volem
+agafar una idea de com resol un problema una funció, sense haver d'entendre al
+100% com ho fa.
+
+És molt típic el problema de posar més comentaris del compte, sobretot en
+programadors novells. Només s'ha de tenir en compte una regla: no expliqueu COM
+resol el problema el vostre tall de codi. Simplement expliqueu QUÈ resol, o fins
+i tot doneu una referència a un mètode conegut. Però sobretot, no expliqueu mai
+COM ho feu. El codi ha de ser prou bo com perquè el que vulgui saber COM es fa,
+ho entengui llegint-lo.
+
+(MANIES DE FER LLARGS SEPARADORS HORITZONTALS ENTRE COSES !? )
+(CAPÇALERES DE FITXERS, GPL, ... )
+
+
+                         11. Definicions i doxygen
+
+Tots els comentaris del doxygen (així com els comentaris de mètodes, variables,
+funcions, classes i enumeracions) estaran a les definicions o prototipus.
+Aquests seran els més restrictius; inclouran els paràmetres per defecte, i
+altres informacions sobre les funcions: virtuals, estàtiques, constants...
+
+Tots els mètodes que siguin correctes en un objecte constant, ho indicaran. Les
+definicions dels que siguin reimplementables en herència, indicaran virtualitat.
+I les que no depenguin de les dades, indicaran estàtica.
+
+(EXPLICIT ?)
+
+Tots els mètodes i variables que puguin ser utilitzats en herència, seran
+declarats sota 'protected' en comptes de 'private'
+(possiblement serà en la majoria de casos).
+
+
+                               12. Encoding
+
+Tot el codi que escrivim ha d'estar en ASCII.
+Això significa oblidar els accents i caràcters per l'estil. De tota manera, de
+moment podem ser menys restrictius en els comentaris i les sortides de texte; en
+aquest cas utilitzarem ISO-8859-1 (aka Latin1), i totes les sortides de texte
+aniran dins del pertinent mètode estàtic 'tr' de QObject (mirar docs de QT).