Asserzioni implicite / esplicite

1

Durante la revisione del codice, è stato presentato un suggerimento minore sul fatto che alcuni comportamenti impliciti siano resi espliciti. Il revisore ha sfogliato il codice in questione, è diventato confuso dopo aver erroneamente interpretato lo scopo del codice, e ha scoperto la causa solo dopo un'attenta analisi. Di seguito sono riportate la pratica implicita e la pratica suggerita, in questo ordine:

stuffLookup = {--[[functions in here]]}

function doStuff(stuffType, ...)
    assert(stuffLookup[stuffType], "stuffType is not a valid stuff!")(...)
end

function doStuff2(stuffType, ...)
    if stuffLookup[stuffType] then stuffLookup[stuffType](...) else error("stuffType is not a valid stuff") end
end

assert è usato frequentemente senza invocare un'altra funzione come in questo caso, quindi a prima vista il revisore non ha visto un'invocazione così piccola alla fine dell'asserzione e ha assunto che la linea non servisse a nulla dopo un controllo di integrità.

L'argomento a favore della pratica 1 era che è sintatticamente corretto, che è usato nei documenti Lua, che è più veloce e che se qualcuno non ha previsto di essere usato in questo modo è stata colpa loro. L'argomento a favore della pratica 2 era che la natura della pratica 1 poteva essere facilmente fraintesa, che si trattava di un'ideologia implicita che non era sufficientemente leggibile e che considerare le prestazioni era un'ottimizzazione prematura (il codice non era progettato per essere usato frequentemente e il tempo di ricerca era trascurabile)

Ci sono meriti in merito alle preoccupazioni e ai punti di vista di entrambe le parti?

    
posta Drew 09.12.2016 - 23:12
fonte

1 risposta

5

Questo sembra principalmente basato sull'opinione, ma suggerirei l'opzione 3:

  function doStuff3(stuffType,...)
    local stuffCallback = assert(stuffLookup[stuffType], "stuffType is not a valid stuff!")
    stuffCallback(...)
  end

La ragione di ciò è che la doppia parentesi è molto spesso inaspettata e quindi il suo uso viola il Principio di Almostonment . Memorizzandolo in una variabile locale che fornisce un nome per quello che stai facendo, ti assicuri che noi, i lettori, sappiamo che il codice sta chiamando una funzione, quindi non è particolarmente sorprendente vedere la parentesi.

Manterrai l'asserzione, quindi dovrebbe morire in modo appropriato, essere facilmente trovata cercando, mostra esattamente cosa intendi fare ed essere relativamente performante (non sono un esperto delle prestazioni delle variabili locali di Lua in contrapposizione ai valori transitori , però).

Per quanto riguarda i pregi e le preoccupazioni di ogni visione: la sintassi corretta non è praticamente un argomento valido --- se funziona è sintatticamente corretto. Qualcosa che viene usato nella documentazione non è nemmeno un segno che sia "buono". La documentazione spesso omette le cose per chiarezza, o concisione, o lo fa solo perché l'autore ha pensato che fosse intelligente. Per quanto riguarda la colpa, non importa chi è in colpa. Ciò che importa è che un numero non trascurabile di manutentori dovrà dedicare più tempo e energie mentali alla comprensione del sistema che potrebbe altrimenti essere utilizzato per migliorare il sistema. Tuttavia, la pratica 2 ha i suoi problemi che non hai menzionato. È più difficile da cercare. È meno sintetico. È meno DRY . Leggere "asserire" ti dice esattamente che questo era inteso come un'asserzione, mentre leggere l'if-else ti fa spendere energie mentali per determinare che questo è un condizionale di validazione. È anche così lungo che richiede lo scorrimento della domanda, ma questo movimento in eccesso orizzontale è anche un possibile problema con la pratica 1. Rompenderlo in unità discrete mantiene il flusso del codice verticale, dove è più facile da seguire.

    
risposta data 09.12.2016 - 23:24
fonte

Leggi altre domande sui tag