cg-Cad

Lisp »Tips 'n Tricks »Variabili locali e globali

Una variabile è globale se non viene forzata come locale.
Una variabile globale resta in vita fino a quando il disegno resta aperto e rimane disponibile per qualsiasi funzione, per ogni voce di menu e sulla linea di comando.
Per visualizzare il valore di una variabile globale si digita il nome della variabile preceduto dal simbolo !. Ad esempio:

Command: (setq a "prova")
"prova"

Command: !a
"prova"

La variabile 'a' contiene la stringa 'prova' per tutto il tempo che resto all'interno del disegno aperto o fino a quando non attribuisco alla variabile un altro valore con la funzione setq. Esempio:

Command: (setq a "prova")
"prova"

Command: !a
"prova"

Command: (setq a 0.34)
0.34

Command: !a
0.34

E' possibile creare una variabile locale dichiarandola nella lista degli argomenti di DEFUN quando si definisce una funzione.

(defun nome (argomenti ... / locali ...) corpo della funzione ...)

Le variabili dichiarate nella lista degli argomenti di DEFUN sono di tipo locale e riferite esclusivamente alla funzione stessa. Terminando la funzione spariscono dalla memoria di AutoCAD.

Ecco un esempio che mostra l'uso delle variabili locali:

(defun f1 ( v1 / v2)
 (princ "\n Sono in f1")
 (setq v2 0.15) ;inizializzo v2
 (setq v1 (+ v1 v2)) 
 ; adesso v1 = 1 + 0.15
 (princ "\n v1 = ")
 (princ v1)
 (princ " v2 = ")
 (princ v2)
 (princ)
)

(defun c:lg ( / v1)
 (setq v1 1)
 (princ "\n Sono in Main")
 (princ "\n v1 = ")
 (princ v1)
 ; chiamo f1 passandogli v1
 (f1 v1) 
 (princ "\n Torno in Main")
 (princ "\n v1 = ")
 (princ v1)
 (princ " v2 = ")
 (princ v2)
 (princ)
)

E questo è il risultato:

Command: lg

 Sono in Main
 v1 = 1
 Sono in f1
 v1 = 1.15  v2 = 0.15
 Torno in Main
 v1 = 1  v2 = nil

Fuori dal campo di esistenza della variabile locale (ad esempio per v2 la funzione f1) il contenuto della variabile locale è sempre nil, così terminata in modo corretto la funzione tutte le variabili locali sono inizializzate con nil:

Command: !v1
nil

Command: !v2
nil

E se non passassi a f1 il valore di v1?

(defun f1 ( / v2)
 (setq v2 0.15)
 (setq v1 (+ v1 v2))
 (princ "\n Sono in f1")
 (princ "\n v1 = ")
 (princ v1)
 (princ "  ")
 (princ "v2 = ")
 (princ v2)
 (princ)
)

(defun c:lg ( / v1)
 (setq v1 1)
 (princ "\n Sono in Main")
 (princ "\n v1 = ")
 (princ v1)
 (f1)
 (princ "\n Torno in Main")
 (princ "\n v1 = ")
 (princ v1)
 (princ "  ")
 (princ "v2 = ")
 (princ v2)
 (princ)
)

Questo è il risultato:

Command: lg

 Sono in Main
 v1 = 1
 Sono in f1
 v1 = 1.15  v2 = 0.15
 Torno in Main
 v1 = 1.15 v2 = nil

Se la variabile non viene esplicitamente passata all'atto della chiamata della funzione allora il suo eventuale uso all'interno della funzione chiamata è sempre per riferimento (cioè la variabile x fa riferimento alla stessa locazione di memoria in cui è memorizzata la variabile x inizializzata in Main); cioè nell'esempio la funzione f1 non lavora su una copia di v1 ma sulla stessa v1.

Nel primo caso invece la funzione f1 opera su una copia di v1. In questo tipo di passaggio per valore si ha una protezione dei dati che non possono essere alterati dal codice della funzione.
La variabile può essere cambiata, modificata, nilizzata o cangiare da numero a stringa ma terminata la funzione (l'azione) torna a rivestire i suoi vecchi panni... insomma come diceva lo slogan: "non è un uccello e non è nemmeno un aereo quella calzamaglia che vola nel cielo" ma Superman cioè Clark Kent come local hero: una variabile passata per valore ad una funzione.

Lisp »Tips 'n Tricks