Hopp til innholdet

cjohansen.no

Tabs vs spaces

For å kaste bensin på et bål som allerede har brent lenge og vel slenger jeg meg inn i "tabs vs spaces"-debatten. Hvordan bør man egentlig indentere kildekode?

Indentering

Når vi skriver kildekode indenterer vi hver gang vi innfører et nytt skop. Nye skop innføres feks når vi lager if-tester, metodedefinisjoner, eller når vi legger innholdet i et blokkelement, så som div i markup på egen/egne linje(r).

Indentering hjelper utviklere å orientere seg i koden ved at alle blokker/skop er tydelig forskjøvet fra hverandre. Enkelte språk, så som Python, har gjort det påkrevd å indentere kode skikkelig.

Fakta

Før vi begynner å synse, er det greit å fremlegge fakta, så vi er enige om hva vi diskuterer. Jamie Zawinski har oppsummert faktaene godt, og han trekker frem:

  1. Visning: Når folk ser på kode bryr de seg om hvor store innrykkene fra venstresiden er.
  2. Lagring: Når en fil inneholder tegnet \t (tab/ASCII #9), hvordan skal den tolkes/vises?
  3. Tastaturet: Hva skjer når utvikleren trykker på tab-tasten på tastaturet?

Hvorfor diskutere?

Hvorfor trenger vi en diskusjon som dette? Vel, om du aldri forandrer mening, jobber alene og heller ikke har planer om å jobbe med andre så kan du egentlig droppe hele diskusjonen.

Men, jobber du med andre er det viktig å diskuterere dette - om ikke med meg så ihvertfall med de du jobber med (men gjerne med meg au). Det er viktig fordi det er sannsynlig at det i en prosjektgruppe er delte meninger om ett eller flere av punktene over.

Er ikke utviklerne enige om disse tingene vil man sannsynligvis få problemer med:

Alternativer

Det er stort sett to måter å indentere kildekode på:

  1. Med mellomrom (spaces)
  2. Med tabs ( \t)

Et tredje valg, som i mine øyne ikke er et reellt valg, er å blande etter eget forgodtbefinnende. Det eneste positive man kan si om noe sånt er at man slipper å tenke på hva man driver med.

Spaces

Velger man space til å indentere kode med er punkt 2 og 3 i lista over løst: Møter editoren på en \t skal det vises x antall mellomrom, og når utvikleren trykker på tab-tasten skal det settes inn x antall spaces.

Går man for spaces må utviklerne enes om hvor mange space ett nivå skal indenteres. Dette kan vise seg å være vanskeligere enn man tror. Dessuten; hva gjør man om noen har forskjellige preferanser i forskjellige kontekster?

Tabs

Tabs løser også punkt 2 og 3: Møter editoren på en \t vises den frem slik den enkelte utvikler har spesifisert, og om utvikleren trykker på tab-tasten så settes det inn en \t i fila.

Punkt én på lista forsvinner også med tabs, fordi det nå blir opp til hver enkelt utvikler hvordan de ønsker at en tab-karakter skal vises (ihvertfall i en relativt velfungerende teksteditor).

Hva skal man velge?

Så hva velger man? I motsetning til mange andre innlegg i denne evige krigen har jeg tenkt til å komme med et nøytralt det ekke så nøye. Jeg mener ikke med det å si at jeg ikke har preferanser, men snarere at det er viktigere at alle som jobber sammen er enige enn at man velger det ene over det andre.

Personlig syns jeg det er naturlig å trekke paralleller fra denne diskusjonen til semantisk HTML. Formålet med semantisk HTML er å beskrive et dokument på en så rik og meningsfull måte som mulig - lister tagges som lister, headinger som headinger osv.

Det motsatte av semantisk HTML ville være å kode en liste som tekst med <br />-elementer mellom (og kanskje også en god gammal &bull;), eller en heading som <p><strong>Overskrift</strong></p>. Jeg tror de fleste ville være enig med meg at <hx> ville vært et bedre valg for en overskrift.

Kildekode som HTML

Hvis vi tenker oss at vi skulle skrevet markup for kildekode så ville vi møtt på innrykkene, om enn ikke direkte. En måte å se en kildekodelisting på er rett og slett som en liste med linjer. Det ville derfor være naturlig å kode hver linje som et <li>-element.

Et annet alternativ kunne være en liste med blokker, som igjen inneholdt en liste med linjer. Denne siste metoden ville gitt oss full kontroll over innrykkene i form av nestede lister. Vi kunne påført frekk logikk for å ha differansierte innrykk, og innrykk i milimeter fremfor antall tegn osv.

Har vi ikke en nestet liste må vi representere innrykkene annerledes. En måte er å hardkode space i form av feks   (no breaking space). Dette gir innrykk, men ikke med samme fleksibilitet som over. Et bedre alternativ kunne vært et element som anga innrykk, ala <div class="indent"></div>. Fleksibiliteten er tilbake.

Space eller tab?

Vel, tilbake til det opprinnelige spørsmålet. Utifra markup-vinklingen virker det soleklart for meg at man bør gå for tabs. Tabs lar det være opp til enhver hvordan man skal se koden sin. Merk at denne enhver også omfatter ditt fremtidige jeg, det kan jo være du skifter mening/preferanser.

En serie med mellomrom er bare det, mens én tab-karakter angir et semantisk innrykk som man står fritt til å definere bredde og betydning av selv. Såfremt tab-karakteren ikke skaper andre problemer ville jeg personlig foretrekke den.

Oops, unntak!

Et siste poeng skal gjøres, og det er tilfellet der jeg mener det er helt streit å blande. Når vi skriver kode så bruker vi white-space først og fremst til indentering, men ikke så rent sjeldent også til "ascii-formattering". Altså, vi antar en monospace-font, og plasserer bokstavene i gitte mønstre for å lette lesligheten.

Bruker vi tabs til å indentere er det viktig å ikke bruke tabs til annen formattering som er avhengig av tekst på andre linjer osv. Dette fordi et av hovedargumentene for tabs er nettopp friheten fra den visuelle fremstillingen - vi kan ikke gjøre antagelser om tab-bredde. Et eksempel hjelper:

// Dette eksempelet er kodemessig tull
// Det er indenteringen som teller her
function testFunksjon() {
 var str = "Dette er en kjemepelang streng. Den er så lang at det er naturlig " +
           "å splitte den over to linjer";

 if (str === '') {
  return null;
 }

 return str;
}

Her brukes det tabs til alle innrykkene unntatt deler av innrykket før "å splitte den over to linjer";. Grunnen til dette er at denne tekststrengen er ment å stå rett under der tekststrengen på linja over begynner, og er altså avhengig av antall tegn fra første innrykk. Den andre delen av strengen er dermed rykket inn med en tab og 10 spaces. Hadde vi brukt feks 3 tabs og 2 spaces ville dette ikke ha fungert om vi endret tab-bredden i editoren. Merk at dette er monospace-font-avhengig.

Hvordan indenterer du din kode?

2006 - 2012 Christian Johansen Creative Commons Lisens