tisdag 19 oktober 2010

Ternary operators i Java

Okej, jag kan vara lätt kod-fascistisk ibland, och jag uppskattar ett fläskigt syntax-solo lika mycket som the next nerd, men ternary operators, eller shorthand eller the child ny any other name osv borde avskaffas omedelbart i kod som skall läsas av många människor. Jag är ju ogärna gnällig men efter att ha stött på detta fenomen som kräver massor av tid varje gång av mig (eftersom det inte är direkt uppenbart vad ditt statement gör så måste jag naturligtvis läsa det och tolka det) så tänkte jag att jag bloggar en liten kommihåglapp så jag kan översätta snabbare.

Ta exemplet
minVal = (a < b) ? a : b;
där vi trivialt sätter det minsta av 2 värden (a och b då i det här fallet) till minVal. Motsvarande vanlig ifsats borde typiskt vara
if ( a < b ) { minVal = a; } else { minVal = b; }
men det är ju helt förkastligt att skriva om man vill imponera på folk med sin syntax-skill. Vilket natruligtvis är häftigt i nördsammanhang där och då, men när nyanställda putte ska laga ett PMD-fel från cruisecontrollen och hittar en lång jäkla harrang som han inte riktigt hänger med i så öppnar man ju upp för skapande av ett fel i koden som enbart beror på att man inte kunde kamma sig och skriva en vanlig bond-ifsats istället.

Naturligtvis är det inte fel att använda denna fina funktion som Sun stoppat in i specen, men jag skulle säga att det nog kan tänkas vara moraliskt snarare än tekniskt. Generellt så funkar det iaf så här
resultat = test ? värde1 : värde2;
eller med if/else
if ( test ) { resultat = värde1; } else { resultat = värde2; }
så det är ju förstås inte helt svårt när man väl vänjer sig. Ett bra exempel taget ur vanliga livet (något förvanskat förstås men ändå) är följande.
Iterable<Grupp> kanskeTom = listaMedPoster.iterator().hasNext() ? listaMedPoster : Arrays.asList(Grupp.EMPTY);

och efter en städning (fick PMD-warnings på raden)
Iterable<Grupp> kanskeTom = null; 
if(listaMedPoster.iterator().hasNext()) {  
    kanskeTom = listaMedPoster 
} else 
    kanskeTom = Arrays.asList(Grupp.EMPTY);  
så nästa gång du funderar på att köra shorthand, tänk på mig som istället för att skumma igenom din kod kommer behöva tänka flera sekunder till på din ifsats.

2 kommentarer:

  1. Jag håller med dig i princip. Kod skall vara svår att skriva men lätt att läsa.

    Det är att föredra att dela upp krångliga if-satser i delar med variabeltilldelning om det gör saken lättare att läsa.

    Exempel som gärna delas upp:

    if ((a < 1) && (!((b > 2)|| (c != 3))) ....

    men att argumentera mot något så elegant och enkelt som tertiäroperatorn tänker jag inte gå med på.
    På vilket sätt är detta svårara att läsa?

    final String result = (bean != null) ? bean.getValue() : null ;

    än följande:

    final String result ;
    if (bean != null) {
    result = bean.getValue() ;
    } else {
    result = null ;
    }

    Det finns andra djur i java-syntaxen som kan kan kallas styggleser men "don't touch my ternery operator"!

    SvaraRadera
  2. Jag håller i princip med om att teriära operationer är stiliga och så vidare, dock gör de inte alltid direkt några underverk med läsbarheten vilket var mer min poäng. Självklart har de sin plats, men ett överdrivet användande kan verkligen göra en ful if-sats värre. Dock tycker jag vi kan kosta på oss att göra en knapp vi kan ha på kavajslaget med texten "Rör inte mina teriäroperationer!" i form av den klassiska handen :)

    SvaraRadera