Cosa c’è di più noioso che scrivere codice di pulizia ripetitivo in ogni possibile punto di uscita di un metodo complesso?
Che si tratti di gestire la chiusura di documenti, reimpostare flag interprocessuali o liberare risorse, garantire che le attività di pulizia vengano eseguite in modo impeccabile, indipendentemente da come o dove la funzione termini, ha sempre richiesto un’attenta pianificazione strutturale. Se un metodo si interrompe inaspettatamente o incontra un Return anticipato, dimenticare una singola riga di pulizia può portare a perdite di memoria o risorse bloccate.
A partire da 4D 21 R4, queste preoccupazioni appartengono al passato. Date il benvenuto al nuovo comando defer: un comando di controllo del flusso potente e moderno, progettato per rendere il vostro codice 4D più pulito, più sicuro e molto più elegante.
Scopriamo insieme come funziona e come trasformerà il modo in cui scrivete il codice 4D!
Cos’è il comando defer?
Il concetto è meravigliosamente semplice: il comando defer vi permette di impilare un’espressione che verrà eseguita automaticamente solo quando il metodo o la funzione corrente avrà terminato l’esecuzione.
Quando il flusso di esecuzione incontra un’istruzione defer, non esegue immediatamente l’espressione. Al contrario, la inserisce in modo sicuro in uno “stack differito” interno dedicato.
La magia avviene quando il metodo o la funzione termina. Indipendentemente da come si completa, 4D preleverà automaticamente tutte le espressioni dallo stack differito e le eseguirà in ordine LIFO (Last In, First Out).
Questa esecuzione garantita si attiva in tutti gli scenari di uscita:
- Completamento normale: quando il flusso di esecuzione termina naturalmente.
- Uscite anticipate: quando viene incontrata ed elaborata un’istruzione Return.
- Interruzioni impreviste: anche se si verifica un errore irreversibile e l’utente conferma l’interruzione, 4D garantisce che le espressioni differite vengano eseguite per ripulire l’ambiente in modo sicuro.
Casi d’uso pratici
Per comprendere la potenza di defer, esaminiamo due esempi classici in cui questo comando semplifica radicalmente lo sviluppo.
Gestione delle risorse a prova di errore
Quando si ha a che fare con risorse esterne come alberi XML, transazioni di database o altro, è necessario assicurarsi che siano chiuse correttamente per evitare perdite di memoria. Con defer, è possibile affiancare il codice di allocazione e quello di pulizia:
var $root:
:= ("rootName")
( ( ))
Text
$rootDOM Create XML Ref
// Ensure the XML tree will be closed and memory freed, no matter what happens next!
deferDOM CLOSE XML$root
// Do something with the $root tree...
Ripristino degli stati dell’ambiente e del database
A volte il codice deve modificare temporaneamente un parametro globale del database o un’impostazione dell’ambiente (come l’attivazione di una registrazione diagnostica approfondita per un’operazione complessa specifica) e garantire che venga ripristinato al suo valore originale in seguito. Il comando defer gestisce questo ripristino dello stato in modo eccellente:
// Get the current state of diagnostic log recording
$logRecording:=Get database parameter(Diagnostic log recording)
// Temporarily enable it for this specific process/method
SET DATABASE PARAMETER(Diagnostic log recording; 1)
// Guarantee the original state is restored as soon as the method/function exits!
defer(SET DATABASE PARAMETER(Diagnostic log recording; $logRecording))
// Execute your complex or heavy operations here...
Esecuzione sicura fin dalla progettazione
Abbiamo progettato questa funzionalità pensando alla sicurezza e alla robustezza. Non dovrete preoccuparvi che un’operazione di pulizia fallita interrompa il flusso di uscita della vostra applicazione.
Se un’espressione eseguita dallo stack differito genera un errore, 4D lo intercetta automaticamente in background senza alcuna interruzione. Continua senza soluzione di continuità l’esecuzione del resto dello stack, comportandosi esattamente come se l’espressione fosse stata eseguita all’interno di un blocco try implicito.
Per mantenere il codice semplice ed evitare loop infiniti o comportamenti imprevedibili, abbiamo anche implementato alcune regole di salvaguardia:
- Nessun annidamento: se un’espressione differita contiene altre istruzioni defer, queste espressioni annidate vengono semplicemente ignorate.
- Nessun ritorno interno: se un’istruzione Return viene accidentalmente chiamata all’interno di un’espressione differita, non verrà eseguita.
Una valutazione intelligente del contesto
Quando le espressioni differite vengono eseguite alla fine di un metodo/funzione, 4D gestisce il contesto delle variabili senza soluzione di continuità: le variabili locali standard mantengono i valori che avevano nel momento esatto in cui sono state differite, mentre le variabili di processo, le variabili locali degli oggetti e i record classici riflettono il loro stato finale al completamento del metodo/funzione.
Conclusione
Disponibile a partire da 4D 21 R4, il comando defer è più di una semplice comodità; è un aggiornamento strutturale per il vostro flusso di lavoro di sviluppo. Raggruppando l’inizializzazione e la pulizia all’inizio della vostra logica, il vostro codice diventa più leggibile, più gestibile e più resistente a interruzioni di runtime impreviste.
Siete pronti a scrivere applicazioni 4D più pulite e sicure? Diteci cosa ne pensate sul Forum 4D!
Al momento non è possibile lasciare commenti su questo post.