Scopo dei messaggi di asserzione

4

Alcune lingue e librerie possono associare messaggi di asserzione con asserzioni. Tali messaggi di asserzione sono inclusi nei messaggi di errore quando l'asserzione non è valida. Esempi sono Java , Class :: Contract, < a href="https://github.com/stuartherbert/ContractLib"> ContractLib e in una certa misura Eiffel stessa (etichette).

Se non ho trascurato qualcosa, i messaggi di asserzione possono (1) descrivere l'asserzione o (2) descrivere la situazione quando l'asserzione non regge:

// describes the assertion
assert !socketChannel.isBlocking() :
    "the socket must not be blocking to be selectable";

// describes the situation when the assertion does not hold
assert !socketChannel.isBlocking() :
    "the socket is blocking and thus not selectable";

Entrambi i tipi di messaggi di asserzione possono essere sostituiti da commenti.

La documentazione di Oracle lascia la semantica al programmatore e afferma che lo scopo dei messaggi di asserzione è aiutare il programmatore. Quindi presenta la scelta come una preferenza personale. Tuttavia, vorrei essere più obiettivo su questa scelta. Il mio attuale pensiero è questo come segue: Idealmente, l'affermazione è auto-esplicativa e non ha bisogno di descrizioni. In tal caso, è meglio descriverlo in un commento piuttosto che in un messaggio di asserzione poiché la descrizione si riferisce al codice. Gli utenti non dovrebbero mai vedere errori di asserzione (eccezione non rilevata in generale) e quindi il messaggio di asserzione non ha bisogno di descrivere cosa è andato storto.

C'è una spiegazione aggiuntiva su quale tipo di messaggi di asserzione è migliore o perché entrambi i tipi non sono necessari (a parte le preferenze personali)?

    
posta user3998276 04.11.2015 - 00:15
fonte

4 risposte

6

Sembra che tu stia dividendo le persone che potrebbero incontrare gli errori lanciati dall'asserzione in due categorie:

  1. Tu, che dovrebbe essere in grado di capire cosa è andato storto dal messaggio generato automaticamente e che inizierà il debugging dalla definizione
  2. Gli utenti finali, che non avrebbero dovuto mai incontrare l'asserzione in primo luogo e che invieranno il testo di asserzione a te / apriranno un ticket nel tuo bug tracker / smetteranno di usare il tuo prodotto e passeranno al concorrente / citare in giudizio per aver causato per perdere preziosi dati commerciali

Questo può o non può essere vero per il tuo progetto, ma nella maggior parte dei progetti di dimensioni ragionevoli esistono altre categorie di persone:

  • Altri programmatori che usano la tua libreria
  • I tuoi compagni di squadra, lavorando su altre parti del progetto
  • Collaboratori di progetti open source, limitando le loro modifiche a parti specifiche del progetto
  • Tu stesso , due mesi dopo l'ultima volta che hai violato l'area del progetto

Queste persone sono fondamentalmente diverse dalle due categorie originali:

  1. A differenza di te, non hanno familiarità con la parte del codice in cui risiede l'affermazione. Guardare un codice sconosciuto scritto da altri popoli è raramente un passatempo molto piacevole - anche se quel codice è ben progettato e documentato.
  2. A differenza dei tuoi utenti finali, non hanno il privilegio di non dover comprendere le asserzioni. Sono sviluppatori, ed è perfettamente normale che gli sviluppatori utilizzino funzioni / classi / moduli errati e attivino le asserzioni lì.

Quindi, queste persone vedranno le affermazioni e avranno bisogno di capirle (perché potrebbe essere il loro codice che ha fatto qualcosa di sbagliato), ma non saranno così constrongvoli come si sta andando alla dichiarazione di asserzione reale, guardando è circondare e capire cosa stava succedendo. Se stavate già scrivendo un commento che descrive cosa (credete) è andato storto quando viene attivata questa affermazione, perché non metterla nel messaggio di errore di asserzione e rendere più facile la vita di questi programmatori?

    
risposta data 04.11.2015 - 01:42
fonte
1

Riguardo a ciò che il messaggio associato dovrebbe descrivere, dovresti attenersi al modulo assertivo che esprime ciò che è previsto. Questa non è solo una preferenza: se provi a spiegare cosa è andato storto, dovrai negare la tua logica nella stringa e in effetti potrebbe diventare falso o ambiguo. Spiega solo cosa doveva succedere.

Ma questo non è abbastanza.

Dovresti fornire più contesto e rendere le tue ipotesi ancora più esplicite dicendoci perché l'asserzione dovrebbe contenere. In nessuna lingua specifica:

assert (sensor >= threshold) : 
  "Sensor is assumed to be above threshold at this point
   because we are in a tightly optimized function (well, 
   that's what Greg always claims) and the caller is 
   responsible for doing sanity checks (see check-sensor
   function)."

(sebbene il commento passivo-aggressivo, sebbene utile, dovrebbe probabilmente essere rimosso)

Se vuoi impedire agli utenti di vedere asserzioni e / o eccezioni, perché fermarsi alla stringa? commenta l'intera espressione! Più seriamente, dovresti gestire le tue eccezioni ogni volta che puoi fornire un feedback utile e possibilmente percorsi alternativi. A volte il tuo codice è semplicemente sbagliato, nonostante il tuo impegno e il tuo sistema lascerà che il messaggio di errore interno risalga al più alto livello del codice. Ma questo è ancora valido, puoi prenderli e registrarli prima che raggiungano lo schermo.

    
risposta data 04.11.2015 - 04:30
fonte
1

Come utente finale, non mi importa meno di un'affermazione. Ha lo scopo di proteggere "la tua implementazione". Quindi vorrei che il messaggio mi dicesse cosa ho fatto di sbagliato e / o cosa dovrei fare per risolverlo.

Non c'è assolutamente niente di sbagliato nel lasciare il messaggio fuori se il "messaggio di asserzione generato automaticamente" soddisfa il mio requisito sopra, ad es. le due asserzioni che hai fornito nella domanda.

Ma non sarei felice se l'asserzione fosse qualcosa come _n > (0.75 * _m) && _free_nodes < (0.3 * _max_size) . In questo caso, apprezzerei un messaggio che diceva:

Please check the capacity limits set on this graph at the time of creation. Either increase the max capacity or respect it.

P.S. Non cercare di decifrare la condizione di asserzione. Volevo solo scrivere qualcosa che un utente finale non capirà.

    
risposta data 04.11.2015 - 17:56
fonte
1

Users should never see assertion errors (uncaught exception in general) and therefore the assertion message does not need to describe what went wrong.

In molti contesti, le asserzioni sono meglio utilizzate per individuare i bug (errori del programmatore) - cose che non dovrebbero mai accadere. Sono idealmente catturati nei test interni prima che raggiungano le mani dell'utente (e spesso servono allo scopo di individuare più problemi in anticipo durante i test interni anziché far passare i problemi agli utenti). Sono diversi dall'eccezionale flusso di controllo che è in genere il risultato di un errore esterno al di fuori del controllo del programmatore (provare a caricare un file corrotto, ad es.) E non in realtà un bug.

Nell'improbabile (ma non sempre impossibile) evento che possono e finiscono per raggiungere l'utente, dovrebbe essere ovvio quale tipo di messaggio di errore di asserzione sembra meno orribile per un utente normale.

Is there an additional explanation of which type of assertion messages is better or why both types are unnecessary (other than personal preference)?

Forse potrebbe essere utile eseguire ulteriori errori di asserzione?

Ad esempio, potrei eseguire una compilazione di debug di un'applicazione in un ambiente di team dopo aver acquisito nuovo hardware e driver ed eseguire un errore di asserzione come:

"Impossibile allocare l'oggetto buffer vertice!" .

Aha! Immediatamente so che il problema è nel codice GPU. Potrebbe non essere nemmeno una mia responsabilità, potrebbe essere il codice di Fred. Ora posso semplicemente rimbalzare il problema su Fred senza nemmeno studiare il suo codice sorgente.

Se ho il controllo del codice, tende ancora a darmi molte informazioni su quello che è successo a colpo d'occhio, che può essere piuttosto rilassante.

L'alternativa ai commenti consiste nel scavare nel codice sorgente, nella riga esatta del codice e nel file di origine in cui l'asserzione ha avuto esito negativo, quindi leggere i commenti, con un messaggio di errore dell'asserzione come:

Errore di asserzione in some_path / something / some_source.ext: 119: assert (successo) .

E anche quel piccolo momento di suspense in cui ora si scava in quel file sorgente citato e si va al numero di linea specificato per cercare di capire cosa diavolo è successo può essere piuttosto stressante, specialmente perché le asserzioni non dovrebbero mai fallire (ma a volte lo fanno comunque, facendoli davvero spiacevoli sorprese).

In generale è molto più stressante per me se entro nel mio appartamento a luci spente e le persone iniziano a urlare "RARRRRRGH!" in cima ai loro polmoni prima di cantare buon compleanno. È molto meno stressante se salta quella parte e inizia a cantare tanti auguri. "Phew, ecco perché mi hanno sorpreso!"

Direi che è piuttosto un sollievo dallo stress almeno per vedere più informazioni relative al motivo per cui un'affermazione ha fallito immediatamente nello stesso senso senza scavare nel file sorgente dove si è verificato dopo ottenendo quello sorpresa a sorpresa.

Nello stesso senso, se il tuo codice non riesce a compilare, non vuoi andare a cercare un numero di riga specifico di un file esterno contenente documentazione per ottenere anche una descrizione umana a distanza del perché la compilazione non è riuscita. È molto più rilassante conoscere il problema prima e avere almeno un po 'di informazioni in più sul motivo per cui questo errore imprevisto si è verificato il più rapidamente possibile dal momento che altrimenti ti lascerà di cattivo umore. Immagina se gli errori di compilazione ti mostrassero un dump esadecimale seguito da una citazione di un numero di riga specifico di un file di documento esterno tramite il quale puoi cercare la causa dell'errore.

Per i messaggi di errore, direi che le informazioni più lusinghiere sono spesso informazioni contestuali che ti forniscono un buon indizio su dove si è verificato l'errore (da un punto di vista di alto livello che non richiede a un numero di riga specificato di un file sorgente specificato) e non semplicemente perché si è verificato, poiché è tipicamente la prima reazione istintiva quando si incontra un fastidioso assertion failure ("Dove diavolo è successo?" che può a volte è una preoccupazione ancora più immediata del perché sia accaduto).

    
risposta data 31.12.2015 - 09:32
fonte

Leggi altre domande sui tag