Qualcuno può / può sfidare lo zio Bob nel suo amore per la rimozione di "apparecchi inutili"?


94

Odio fare riferimento a contenuti a pagamento, ma questo video mostra esattamente di cosa sto parlando. Esattamente 12 minuti in Robert Martin guarda questo:

Del codice

E dice "Una delle mie cose preferite da fare è sbarazzarsi di parentesi inutili" mentre lo trasforma in questo:

Più codice

Molto tempo fa, in un'educazione molto lontana, mi hanno insegnato a non farlo perché rende facile introdurre un bug aggiungendo un'altra riga rientrata pensando che sia controllata da ifquando non lo è.

Per essere onesti con lo zio Bob, sta rifattorizzando un lungo metodo Java fino a minuscole funzioni che, sono d'accordo, sono molto più leggibili. Quando ha finito di cambiarlo, (22.18) appare così:

Ancora più codice

Mi chiedo se questo dovrebbe convalidare la rimozione delle parentesi graffe. Conosco già le migliori pratiche . Zio Bob può essere sfidato su questo punto? Lo zio Bob ha difeso l'idea?


6
Sto votando per chiudere questa domanda come fuori tema perché qualsiasi risposta a questa sarà "no" o "sì, ed ecco una citazione".
Blrfl,

35
Dagli qualche anno, forse rimuoverà anche l'interruzione di linea inutile e "if (vedi (qualcosa)) dire (qualcosa);" sarà effettivamente essere una riga di codice ;-)
Steve Jessop

8
@SteveJessop Mi fa piacere sapere che sono avanti per anni. : D Senza la nuova riga, non esiste il rischio del famigerato bug. L'aggiunta / rimozione di parentesi graffe secondo necessità è un ulteriore sovraccarico, ma molto di più viene salvato durante la lettura.
Maaartinus,

9
Lo zio Bob fa alcuni buoni punti per farlo in Clean Code, pagina 35. Se un ifblocco è sempre una sola riga, non importa. Se è necessario aggiungere più linee, dovrebbe essere un'altra funzione che riduce il ifblocco a una linea (la chiamata di funzione). Se aderisci a questo, allora le parentesi graffe semplicemente non contano - affatto .

13
dovrebbe fare solo return (page==null) ? "" : includePage(mode,page);se vuole così tanto conciliare ... Ho pensato che lo stile no-brace fosse bello fino a quando non ho iniziato a sviluppare app in modo professionale. Disturbi diff, possibili errori di battitura, ecc. Le parentesi graffe, essendo presenti tutto il tempo, ti fanno risparmiare tempo e spese generali da presentare in seguito.
vaxquis,

Risposte:


47

La leggibilità non è cosa da poco.

Ho una mentalità mista quando si tratta di apparecchi che racchiudono un singolo metodo. Li rimuovo personalmente per cose come dichiarazioni di ritorno a riga singola, ma tralasciare tali parentesi ci ha davvero morso molto all'ultimo posto in cui ho lavorato. Qualcuno ha aggiunto una riga di codice a ifun'istruzione senza aggiungere anche le parentesi graffe necessarie e, poiché era C, ha bloccato il sistema senza preavviso.

Non ho mai sfidato nessuno che sia religioso a usare sempre le parentesi graffe dopo quel piccolo fiasco.

Quindi vedo il vantaggio della leggibilità, ma sono profondamente consapevole dei problemi che possono sorgere quando si lasciano fuori questi apparecchi.

Non mi preoccuperei di cercare uno studio o l'opinione pubblica di qualcuno. Ognuno ne ha uno (un'opinione, cioè), e poiché si tratta di una questione stilistica, un'opinione è buona quasi quanto l'altra. Pensa tu stesso al problema, valuta i pro e i contro e crea la tua maledetta mente. Se il negozio per cui lavori ha uno standard di codifica che copre questo problema, segui semplicemente quello.


7
Ne sono stato morso troppo di recente, quando il rientro era spento e fuorviante.
Andy,

12
Perché era C senza GCC 6-Wmisleading-indentation .
wchargin,

2
@CandiedOrange: è lo zio Bob a sfidare il dogma stabilito.
Robert Harvey,

1
@RobertHarvey Non l'ho chiarito? Sì, sta sfidando il dogma. Sta sfidando il MIO dogma. Sto solo cercando di essere un bravo studente e almeno ci penso. Ma lo zio Bob è così dannatamente carismatico da farmi chiedermi se perdo l'obiettività. Quindi chiedo aiuto per trovare un antidoto prima di bere il koolaid.
candied_orange

1
@CandiedOrange: è assolutamente una questione di contesto. Chi accetta alla cieca il dogma non considera il contesto; sono quelli che usano ancora la regola del "solo ritorno" nelle lingue gestite, molto tempo dopo che la regola è sopravvissuta alla sua utilità ed è diventata effettivamente un ostacolo.
Robert Harvey,

133

Puoi trovare diverse promozioni o rifiuti pubblicati di stili senza parentesi qui o qui o ovunque siano verniciate le biciclette.

Allontanandosi dai capannoni della bicicletta, ricordi il fantastico bug SSL OS X / iOS del 2014?

if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
    goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
    goto fail;
    goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
    goto fail;

Sì, "causato" da blocchi senza parentesi graffe https://www.imperialviolet.org/2014/02/22/applebug.html

Le preferenze possono dipendere dallo stile del controvento. Se dovessi scrivere

if (suiteSetup)
{
    includePage(mode, suiteSetup);
}

Potrei anche essere incline a risparmiare spazio. Ma

if (suiteSetup) {
    includePage(mode, suiteSetup);
}

utilizza solo una riga "extra".


So che non me l'hai chiesto, ma se lavoro da solo, sono un eretico. Se rimuovo le parentesi graffe, preferisco

if (suiteSetup != null) includePage(mode, suiteSetup);

Non ha lo stesso problema visivo del bug in stile SSL iOS, ma salva ancora più linee "inutili" di zio Bob;) Legge bene se ci sei abituato e ha un uso corrente in Ruby ( includePage(mode, suiteSetup) unless suiteSetup.nil?). Vabbè, sappi solo che ci sono molte opinioni.


13
Inoltre, se lo usi } else[if(...)] {, ciò non aggiunge ulteriori righe aggiuntive, quindi aggiunge solo una riga aggiuntiva nell'intera cosa.
Casuale 832

12
Sono contento che tu abbia richiamato il bug SSL iOS. Da allora, mi sono trovato sempre più a usare le parentesi graffe in tali situazioni.
Zach Lipton,

4
Per quanto riguarda il bug "goto fail", vale la pena notare che anche altri aspetti dello stile di codifica di zio Bob lo avrebbero impedito, soprattutto, la sua forte preferenza per metodi estremamente brevi. Non avrebbe mai tollerato un metodo a 79 righe in primo luogo, e se il metodo fosse stato suddiviso in metodi più piccoli (a) il conflitto di unione che ha causato la duplicazione probabilmente non si sarebbe mai verificato e (b) il controllo di flusso più semplice nel metodo avrebbe probabilmente significato che sarebbero stati generati avvisi del compilatore per codice non raggiungibile che avrebbe dovuto prevenire il problema.
Jules,

16
"goto fail" non è stato causato da blocchi a linea singola, è stato causato da una programmazione sciatta, da una revisione del codice ancora più sciatta, e nemmeno da una sola volta nel passare manualmente il codice.
gnasher729,

35
Meh, la mancanza di parentesi graffe non ha causato quel bug. I programmatori spaventosi (e la mancanza di una revisione significativa del codice, test) hanno fatto. Risolvi il problema licenziando i responsabili, non legando le mani di tutti noi!
Razze di leggerezza in orbita

62

Lo zio Bob ha molti livelli di difesa contro un tale errore che non erano così banali quando "usare sempre le parentesi graffe" era la saggezza prevalente:

  1. Una forte preferenza personale per i condizionali a linea singola, quindi quelli a più linee si distinguono e ricevono un controllo extra.
  2. Un editor che supera automaticamente quando inserisci una seconda riga.
  3. Una suite completa di test unitari che esegue costantemente.
  4. Una suite completa di test di integrazione.
  5. Una revisione tra pari eseguita prima della fusione del suo codice.
  6. Una ripetizione di tutti i test da parte di un server di integrazione continua.
  7. Test eseguiti da un dipartimento di qualità del prodotto.

Penso che se qualcuno pubblicasse una sfida per lo zio Bob, avrebbe una confutazione piuttosto buona con i punti precedenti. Questo è uno degli errori più facili da rilevare in anticipo.


16
Non ho mai temuto incidenti come temo cose che falliscono silenziosamente. Almeno sai quando si verifica un incidente. La parte posteriore del mio cervello formicola quando vedo queste cose. Formaggia allo stesso modo in cui lo vedo while(true);{break;}. Se esiste davvero un contesto valido per questo, mi ci vorrà un po 'per superarlo.
candied_orange

9
Abbiamo un modo automatizzato di verificare che includePage()non sia una macro scritta male con più di un'istruzione?
Martin York,

51
@LokiAstari Sì, si chiama "Java non ha macro".
svick,

11
Tutto quanto sopra è più "un modo per evitare che le cadute legate alla politica" bretelle inutili "mi facciano male" che in realtà "ragioni per usare la" polizza bretelle inutili ". I fatti di cui hai bisogno (specialmente n. 1) dovrebbero essere considerati più uno svantaggio che un vantaggio.
SJuan76,

16
@Jules Oh si! TUTTI i prodotti che ho ricevuto o rilasciato sul posto di lavoro hanno una copertura dei test del 100% (per lo meno), sono sottoposti a peer review (più volte) e tutte le attività commerciali hanno dipartimenti di controllo qualità del software. Sì. Immagino che tu abbia trovato lo stesso nella tua carriera professionale, perché ogni azienda ha team di programmatori anziché singoli programmatori e danno loro più del tempo sufficiente per fare tutti i test che vorrebbero fare. Sì, descrive perfettamente tutti i luoghi di lavoro. Perché dovremmo preoccuparci di aggiungere altri bug quando siamo sicuri che il nostro software SEMPRE spedisce SEMPRE al 100% senza bug?
SJuan76,

31

Per la maggior parte questa è una preferenza personale, tuttavia ci sono alcune cose da considerare.

Possibili bug

Mentre si può sostenere che i bug causati da dimenticare di parentesi graffe add-in sono rari, da quello che ho visto che essi si verificano di tanto in tanto (per non dimenticare il famoso goto IOS sicuro bug). Quindi penso che questo dovrebbe essere un fattore quando si considera il tuo stile di codice (alcuni strumenti avvertono di indentazione fuorviante , quindi dipende anche dalla tua catena di strumenti) .

Codice valido (che potrebbe sembrare un bug)

Anche supponendo che il progetto non soffre di questi bug, durante la lettura del codice si possono vedere alcuni blocchi di codice che sembrano potrebbero essere bug - ma non sono, prendendo alcuni dei vostri cicli mentali.

Iniziamo con:

if (foo)
    bar();

Uno sviluppatore aggiunge un commento utile.

if (foo)
    // At this point we know foo is valid.
    bar();

Più tardi uno sviluppatore si espande su di esso.

if (foo)
    // At this point we know foo is valid.
    // This never fails but is too slow even for debug, so keep disabled.
    // assert(is_valid(foo));
    bar();

Oppure aggiunge un blocco nidificato:

if (foo)
    while (i--) {
        bar(i);
        baz(i);
    }

Oppure utilizza una macro:

if (foo)
    SOME_MACRO();

"... Dato che le macro possono definire più righe di codice, la macro utilizza do {...} while (0)per più righe? Dovrebbe essere perché è nella nostra guida di stile, ma è meglio controllare per ogni evenienza!"


Gli esempi di cui sopra sono tutti codici validi, tuttavia, più contenuto nel blocco di codice, più è necessario leggere per assicurarsi che non vi siano errori.

Forse il tuo stile di codice definisce che i blocchi multi-linea richiedono un controvento (non importa quale, anche se non sono codice) , ma ho visto questo tipo di commenti aggiunti nel codice di produzione. Quando lo leggi, c'è qualche piccolo dubbio sul fatto che chiunque abbia modificato quelle ultime righe abbia dimenticato di aggiungere una parentesi graffa, a volte sento che la necessità di ricontrollare sta funzionando come previsto (specialmente quando indaga su un bug in questa area del codice) .

Rumore diff

Un motivo pratico per utilizzare le parentesi graffe per le singole linee è ridurre il rumore diff .

Cioè, cambiando:

if (foo)
    bar();

Per:

if (foo) {
    bar();
    baz();
}

... fa apparire la linea condizionale in una diff come modificata, questo aggiunge un piccolo ma inutile sovraccarico.

  • le righe vengono visualizzate come modificate nelle revisioni del codice, se i tuoi strumenti di differenziazione sono basati su parole, puoi facilmente vedere che è cambiata solo la parentesi graffa, ma ci vuole più tempo per verificare se la linea non è cambiata affatto.
    Detto questo, non tutti gli strumenti supportano il diffing basato su parole, diff (svn, git, hg ... ecc.) Mostrerà come se l'intera linea fosse cambiata, anche con strumenti fantasiosi, a volte potrebbe essere necessario esaminare rapidamente una linea semplice basato su diff per vedere cosa è cambiato.
  • gli strumenti di annotazione (come git blame) mostreranno la linea come modificata, rendendo il tracciamento dell'origine di una linea più un passo per trovare il vero cambiamento.

Questi sono entrambi piccoli e dipendono da quanto tempo dedichi alla revisione del codice o al tracciamento verso il basso che commettono righe di codice modificate.

Un inconveniente più tangibile di avere cambiamenti di linea extra in un diff, la loro maggiore probabilità che cambiamenti nel codice provochino conflitti che si fondono e devono essere risolti manualmente .


C'è un'eccezione a questo, per le basi di codice che hanno {una propria riga: non è un problema.

L' argomento del rumore diff non regge se scrivi in ​​questo stile:

if (foo)
{
    bar();
    baz();
}

Tuttavia questa non è una convenzione così comune, quindi si aggiunge principalmente alla risposta per completezza (non suggerire che i progetti dovrebbero usare questo stile) .


8
Mi piace la riduzione del rumore diff commentato che è un vantaggio definito.
Martin York,

2
Se solo chiunque fosse pazzo di JSON avesse preso in considerazione il rumore diff! Ti sto guardando, regola dell'ultima virgola.
Roman Starkov,

1
Eh, non avevo preso in considerazione il beneficio del rumore diff dello stile {-on-la-sua-linea. Odio davvero quello stile e non mi piace lavorare su progetti in cui è richiesto quello stile. Forse con questo in mente, lo troverò un po 'meno frustrante dover codificare in quel modo. La densità del codice è importante. Se riesci a vedere tutte le funzioni sul tuo monitor in una sola volta, puoi facilmente fare il grok dell'intera cosa. Mi piace lasciare righe vuote tra blocchi di codice separati all'interno di una funzione per leggibilità (per raggruppare le istruzioni correlate), ed essere costretto a sprecare spazio in altri luoghi rende le interruzioni previste più deboli.
Peter Cordes,

1
@ peter-cordes, anche lui non un fan del {suo stile personale, lo ha incluso solo per completezza delle risposte. Per quanto riguarda la fiducia delle macro da usare do{}while(0), trovo che il problema sia che puoi fidarti quasi sempre. Il problema è che si verificano incidenti, gli errori possono sfuggire alla revisione del codice ... e possono essere introdotti bug che non sarebbero stati altrimenti.
ideasman42

2
Se stiamo elencando potenziali bug, la possibilità di commentare singole righe è un'altra cosa positiva. Stavo rintracciando un bug causato da qualcuno che commentava ciecamente il corpo di un'istruzione if di una riga. La seguente dichiarazione è stata quindi eseguita in modo condizionale, anziché eseguita incondizionatamente.
Eldritch Cheese,

15

Anni fa, sono stato introdotto per eseguire il debug del codice C. Il bug era pazzo difficile da trovare, ma alla fine si ridusse a una dichiarazione come:

if (debug)
   foo (4);

E si è scoperto che la persona che l'aveva scritta aveva definito foouna macro. Una macro con due righe di codice al suo interno. E, naturalmente, solo la prima di quelle due righe era soggetta al if. (Quindi la seconda riga è stata eseguita incondizionatamente.)

Questo può essere assolutamente unico per C e il suo preprocessore - che sostituisce prima della compilazione - ma non l'ho mai dimenticato. Questo genere di cose lascia un segno su di te, e perché non giocarci sul sicuro, specialmente se usi una varietà di lingue e toolchain e non sei sicuro che tali shenanigans non siano possibili altrove?

Ora indentro e uso parentesi graffe in modo diverso rispetto a tutti gli altri, apparentemente. Per una singola riga if, farei:

if (debug) { foo (4); }

quindi non sono necessarie righe aggiuntive per includere le parentesi graffe.


6
In tal caso, chiunque abbia scritto quella macro è quello in colpa.
gnasher729,

6
Scrivere correttamente le macro del preprocessore C potrebbe non essere intuitivo, ma può essere fatto. E dovrebbe essere fatto, come sottolinea gnasher729. E il tuo esempio è il motivo per cui ogni macro che contiene più di un'istruzione deve includere il suo corpo in un do { ... } while(0)ciclo. Ciò non solo garantirà che venga sempre trattato correttamente racchiudendo le if()istruzioni, ma anche che il punto e virgola alla fine dell'istruzione venga ingoiato correttamente. Chiunque non conosca regole così semplici, semplicemente non dovrebbe scrivere macro per il preprocessore. La difesa sul sito chiamante è il posto sbagliato da difendere.
cmaster

18
@cmaster: vero, ma il modo in cui le macro (o altre funzionalità del linguaggio) sono scritte da altri è al di fuori del mio controllo. Come uso le parentesi graffe è sotto il mio controllo. Sicuramente non sto dicendo che questo sia un motivo di ferro per includere le parentesi graffe, ma è qualcosa che posso fare per difendermi dagli errori degli altri, quindi lo faccio.
Wayne,

@ gnasher729, a chi importa se è colpa di qualcun altro? Se stai facendo revisioni del codice e stai seguendo alcuni standard di codice ragionevoli, potrebbe anche essere colpa del tuo team. E se raggiunge gli utenti, daranno la colpa all'organizzazione rilasciando software difettoso.
ideasman42

1
Chiunque abbia inventato le macro è quello in colpa.
Neme,

14

"Zio Bob" può avere la sua opinione, tu puoi avere la tua opinione. Non c'è bisogno di sfidarlo.

Se vuoi un appello all'autorità, prendi Chris Lattner. In Swift, se le dichiarazioni hanno perso la parentesi, ma arrivano sempre con parentesi graffe. Nessuna discussione, fa parte del linguaggio. Quindi, se "Zio Bob" inizia a rimuovere le parentesi graffe, il codice interrompe la compilazione.

Analizzare il codice di qualcun altro e "sbarazzarsi di parentesi inutili" è una cattiva abitudine. Causa lavoro extra solo quando il codice deve essere rivisto e quando vengono creati inutilmente conflitti. Forse "Zio Bob" è un programmatore incredibilmente bravo da non aver bisogno di recensioni di codice? Ho perso una settimana della mia vita perché un programmatore di spicco ha cambiato "if (p! = NULL)" in "if (! P)" senza una revisione del codice, nascosto nel peggior posto possibile.

Questo è principalmente un dibattito di stile innocuo. Le parentesi graffe hanno il vantaggio di poter inserire un'altra riga di codice senza aggiungere parentesi graffe. Come un'istruzione di registrazione o un commento (se seguito da un commento seguito da un'istruzione è semplicemente orribile). dichiarazione sulla stessa riga come se avesse lo svantaggio pratico di avere problemi con molti debugger. Ma fai quello che preferisci.


1
Immagino si tratti di "sfidare" perché UB (sic!) Presenta le sue opinioni come fatti - almeno mi colpisce così quando lo ascolto.
vaxquis,

3
Dire "Fai quello che preferisci" in realtà è d'accordo con lo zio Bob su questo perché è quello che sostiene "non importa". In molte lingue questo non è un problema. In precedenza avevo pensato a tutti quelli in cui è un problema che dovresti SEMPRE usare le parentesi graffe e non avevo visto nessuno sfidarlo. Ora ecco che lo zio Bob lo sta sfidando e mi chiedo se se la cava perché lavora con metodi minuscoli altamente riformattati o perché ne è pieno. Non l'avevo considerato innocuo proprio a causa del tipo di bug menzionato da @PaulDraper nella sua risposta.
candied_orange

Re sempre : il rumore sintattica è fonte di distrazione e la linea più "vuota" per la chiusura parentesi graffa aggiunge un separatore visiva nel paragrafo in cui le linee non devono essere divisi a parte, ostacolando ulteriormente la leggibilità. Ciò è particolarmente importante in piccoli blocchi concisi di cui parli.
JDługosz,

9

Le mie ragioni per non rimuovere le parentesi graffe sono:

  1. ridurre l'affaticamento decisionale. Se usi sempre le parentesi graffe, non devi mai decidere se hai bisogno di parentesi graffe o meno.

  2. ridurre la resistenza di sviluppo: anche se vi sforzate di fine di estrarre tutte le linee multiple di logica per i metodi, dover convertire un braceless se ad un rinforzato se per aggiungere la logica è un po 'fastidioso di resistenza di sviluppo. Quindi c'è lo sforzo di rimuovere le parentesi graffe e lo sforzo di aggiungerle di nuovo quando è necessario più codice. Piccolo, ma fastidioso.


0

Un giovane collaboratore ha affermato che gli apparecchi che riteniamo superflui e superflui gli sono di fatto utili. Non ricordo esattamente il perché, ma se gli consente di scrivere codice migliore più velocemente, questo da solo è un motivo per tenerli.

FWIW, abbiamo concordato un compromesso che la loro messa su una linea non rende tali presupposti brevi un leggibile / distrazione per me. Per esempio

if (!param) { throw invalid_argument (blahblah); }
if (n < 2) { return 0; }
// real code for function starts here...

Sottolineo anche che queste precondizioni introduttive sono spesso dichiarazioni di flusso di controllo per il corpo (ad es. A return), quindi la paura di aggiungere una seconda affermazione che dovrebbe essere nelle stesse condizioni e dimenticare di scrivere parentesi graffe è controversa. Una seconda affermazione sotto la condizione sarebbe comunque un codice morto e non avrebbe senso.

Ho il sospetto che la fluidità nella lettura sia causata dal fatto che il parser cerebrale della persona sia cablato per avere le parentesi graffe come parte dell'istruzione condizionale. Questa non è una rappresentazione accurata della grammatica del C ++, ma potrebbe essere un effetto collaterale dell'apprendimento prima di alcune altre lingue, dove è il caso.


1
Lo zio Bob probabilmente pensa di scrivere meglio il codice più velocemente senza di loro.
Djechlin,

2
Come me, e altri fluenti in C ++.
JDługosz,

1
"se gli consente di scrivere un codice migliore più velocemente, questo da solo è un motivo per tenerli" ++ Ho un Jr. che ha detto lo stesso, quindi li conserviamo.
RubberDuck,

... e questa è quindi solo la ragione per farlo come vuole lo zio Bob.
Djechlin,

-1

Avendo visto quel video proprio ora, ho notato che eliminare le parentesi graffe rende più facile vedere dove il codice deve ancora essere refactored. Se hai bisogno di parentesi graffe, il tuo codice può probabilmente essere un po 'più pulito.

Detto questo, quando fai parte di una squadra, l'eliminazione delle parentesi graffe probabilmente porterà a comportamenti imprevisti un giorno. Dico di tenerli e ti risparmierai un sacco di mal di testa quando le cose vanno male.


questo non sembra offrire nulla di sostanziale rispetto ai punti formulati e spiegati nelle precedenti 10 risposte
moscerino del

-3

Mi è stato insegnato a non farlo perché rende facile introdurre un bug aggiungendo un'altra riga rientrata pensando che sia controllata dal se quando non lo è.

Se il tuo codice è ben testato dall'unità , questo tipo di "bug" esploderà in faccia.

Pulire il codice evitando parentesi inutili e brutte è una pratica che seguo.


9
Ovviamente è vero anche il contrario: se il codice è privo di bug, non è necessario alcun test unitario. La realtà è che viviamo in un mondo imperfetto dove a volte ci sono errori nel codice e talvolta errori nei test. (Nella mia esperienza, questi ultimi sono in realtà più comuni.) Quindi mentre i test certamente riducono il rischio di bug, questa non è una scusa per trovare altri modi per aumentare di nuovo il rischio.
Ruakh,

3
Per aggiungere al commento di Ruakh: non è possibile testare un codice al 100%.
BЈовић,

Per favore, vieni a vedere il mio codice;) Durante la pratica del TDD, è sempre possibile mostrare questo tipo di bug molto rapidamente.
Mik378,

@ Mik378 questo non è assolutamente vero. Il punto è che se hai usato le parentesi graffe, non dovresti nemmeno preoccupartene.
GoatInTheMachine
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.