Jste zde

Proč v kódu nemixovat tabelátory a mezery

Někdo preferuje mezery, někdo tabelátory. Diskuse o tom, který způsob je lepší, bývají nekonečné, protože každý z nich má své pro a proti a každý programátor to vidí jinak, takže to nemá smysl řešit. V následujícím článku bych však chtěl argumentovat, proč není dobrý nápad v kódu tabelátory a mezery mixovat.

Proč ne?

Protože velikost tabelátoru se liší editor od editoru a programátor od programátora. Typická nastavení bývají zobrazovat tabelátor jako 2, 4, či 8 mezer. Pokud mixujete mezery a tabelátory, tak se kód ve vašem editoru sice může zobrazovat korektně, ale jiný programátor uvidí nepořádek a pomyslí si o vás nepěkné věci.

Pojďme na příklad. Dejme tomu, že máte v editoru nastaveno, ať se vám tabelátor zobrazuje jako 4 mezery. Pak může kód, který mixuje tabelátory a mezery vypadat korektně ( značí tabelátor):

if (shouldMove) {
→   →   target->move();} else {
        target->standStill();   // Zde se k odsazení místo tabelátorů použily mezery.}

Pokud má ale někdo nastaveno, ať se mu tabelátor zobrazuje jako 8 mezer, uvidí nepořádek:

if (shouldMove) {
→       →       target->move();} else {
        target->standStill();  // Zde se k odsazení místo tabelátorů použily mezery.}

Buďte proto svědomitý programátor a nemixujte mezery a tabelátory.

Jazyk Python je pak případ sám o sobě. Pokud v něm budete mixovat tabelátory a mezery, buď vám kód bude vyhazovat výjimku IndentationError, nebo (hůř) bude fungovat, ale bude dělat něco jiného, než očekáváte (např. příkaz se přiřadí do jiného bloku, než vidíte v editoru). Důvodem je, že v Pythonu jsou oproti ostatním jazykům bílé znaky signifikantní ze syntaktického hlediska.

Odsazování pomocí tabelátorů, zarovnání pomocí mezer

Někteří programátoři mixují mezery a tabelátory tak, že k odsazení používají tabelátory a k zarovnání mezery. Příklad:

→    →    collide(getFirstObjectInCollision(),
→    →            getSecondObjectInCollision());  // Zde se k zarovnání použily mezery.

Tento kód se zobrazí korektně nezávisle na nastavení editoru. Je zde však jiný problém: při dalších úpravách, ať už autorem či jinými programátory se často zapomene či dojde k přehlédnutí, co se k odsazení a zarovnání použilo. Pokud pak jiný programátor změní název funkce a zarovná pomocí tabelátorů, nastane opět zmatek:

→    →    collideTwoObjects(getFirstObjectInCollision(),
→    →            →    →    getSecondObjectInCollision());  // Zde se mixují mezery a tabelátory.

Typicky totiž v editoru mezery a tabelátory nejsou vidět, takže se špatně rozlišuje, co je kde. Když si pak kód zobrazí někdo, u koho je tabelátor zobrazován jako 8 mezer, zobrazí se mu toto:

→        →        collideTwoObjects(getFirstObjectInCollision(),
→        →                →        →        getSecondObjectInCollision());  // Zde se mixují mezery a tabelátory.

Takže odsazování pomocí tabelátorů a zarovnání pomocí mezer taktéž nedoporučuji.

Zobrazení mixování mezer a tabelátorů v editoru

Abych se vyhnul neúmyslnému způsobování nepořádku při editaci kódu, tak mám ve Vimu nastaveno zvýraznění mixování mezer a tabelátorů:

" Highlight mixture of spaces and tabs
au BufEnter * hi SpacesTabsMixtureGroup guibg=gray18 guifg=red ctermbg=gray ctermfg=red
au BufEnter * match SpacesTabsMixtureGroup /^ \+\t\+\|^\t\+ \+/

Ukázka:
Ukázka zvýraznění mixování mezer a tabelátorů u mě ve Vimu.

Dále mám ve Vimu na klávese F2 nastaveno zobrazení mezer, tabelátorů a konců řádků v kódu:

" Tell Vim which characters to show for expanded TABs, trailing whitespace,
" ends of lines, and non-breakable space
set listchars=tab:>-,trail:#,eol:$,nbsp:~,extends:>,precedes:<
 
" F2: Toggle the display of unprintable characters
nnoremap <silent> <F2> :set list!<CR>

Hodí se to, když se chci podívat, co přesně za bílé znaky (angl. white space) v kódu jsou:

Ukázka:
Ukázka zvýraznění bílých znaků u mě ve Vimu.

Když edituji cizí kód, tak si pomocí F2 zobrazím, co se k odsazení používá, nastavím si příslušně Vim a vesele edituji. Ve Vimu lze např. k odsazení používat pořád klávesu TAB a nastavit si, zda vám má vložit tabelátor nebo ekvivalentní (nastavený) počet mezer. Lze tak pro každý jazyk/projekt použít speciální nastavení.

Další čtení

Přidat komentář