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:
- Visning: Når folk ser på kode bryr de seg om hvor store innrykkene fra venstresiden er.
- Lagring: Når en fil inneholder tegnet
\t(tab/ASCII #9), hvordan skal den tolkes/vises? - 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:
- Utviklere som sløser bort tid på å reformattere filer
- Frustrerte (og dermed mindre effektive) utviklere
- Spamming av versjonskontroll (mange revisjoner vil kun inneholde whitespace-endringer)
Alternativer
Det er stort sett to måter å indentere kildekode på:
- Med mellomrom (spaces)
- 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 •), 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?
Kommentarer
Ola
(http://telenor.no/privat/)
6. oktober, 10:57
Jeg foretrekker en indentering med fire tegn per nivå, stort sett i alle sammenhenger. Mange andre liker å bruke to tegns indentering, spesielt for html (hvor du gjerne får mange nivåer).
Som du så glimrende påpeker kan jeg faktisk sette opp sånt selv i editorene mine, med separate innstillinger for forskjellige språk om jeg vil.
En helt annen ting er naturligvis at ett trykk på tab-tasten er kjappere enn fire trykk på space-tasten. Jeg syns ikke det argumentet er så dårlig heller :)
Christian
6. oktober, 12:21
\tved trykk på tab-tasten også, skulle du ha lyst til det.Ravn
(http://ixd.no)
6. oktober, 14:03
Martin Berglund
(http://macbruker.com)
6. oktober, 14:11
Til mitt bruk har jeg (nesten) konsekvent brukt tabs. Jeg har ikke hatt noen grunner til å velge og bruke spaces, men noterer argumentene i denne posten hvis det skulle dukke opp et behov.
Christian
6. oktober, 14:59
Tastaturnavigasjon er jo en editor-greie. Jeg ser for meg at dette er enklere med tabs, men med en god editor kan man nok navigere effektivt med piltaster i spaces også.
Ola
(http://telenor.no/privat/)
6. oktober, 15:23
Anders
8. oktober, 09:57
Har prøvd å konfigurere Eclipse til å ha forskjellig indentering mellom ulike prosjekter (avhengig av om det er et Symfony prosjekt eller noe annet), men det gav jeg raskt opp, fikk ikke til et oppsett som fungerte 100% og måtte alltid inn et eller annet sted og endre på en setting når man jeg vekslet mellom prosjekter.
Marius Andersen
7. juni, 23:58
Emacs: http://www.emacswiki.org/IntelligentTabs
Vim: http://vim.wikia.com/wiki/Indent_with_tabs,_align_with_spaces
August Z. Flatby
(http://shortcut.no)
18. juni, 16:38
Christian
19. juni, 08:28
Det viktigste er uansett hva man velger å ihvertfall være konsekvent :)
Christian
19. juni, 08:28
august Z. Flatby
(http://shortcut.no)
19. juni, 22:00
Poenget mitt er at hvis kun én person skal se på koden så er det flott å bruke tabs, men hvis flere skal dele koden så ender man fort opp med mye griseri.
Marius Andersen
20. juni, 23:26
«Now, some people will claim that having 8-character indentations makes the code move too far to the right, and makes it hard to read on a 80-character terminal screen. The answer to that is that if you need more than 3 levels of indentation, you’re screwed anyway, and should fix your program.»
Hvis en foretrekker smalere innrykk, blir det opp til en selv å disiplinere seg til å ikke overskride denne grensen.
Christian
21. juni, 20:12
Når det er sagt vil jeg understreke at jeg syns det er viktigere å følge konvensjonene som eksisterer for språket man koder i, om slike eksisterer. For Ruby er det veldig klare konvensjoner som sier 2 space for indentering, og da bør man holde seg til det.
For de språkene hvor det ikke finnes slike sterke føringer foretrekker jeg "tabs for indentation, spaces for alignment" (skulle forsåvidt ønske at det gjaldt alle tilfeller, men man har nå forskjellige meninger :)
Kommentarer er stengt