Le variabili sono parte di una classe di elementi del linguaggio REXX chiamati simboli I simboli sono:
I simboli che iniziano con una cifra (0-9), un punto (.) o un segno (+ o -) sono costanti in quanto ad essi non può essere assegnato un valore e non possono perciò essere usati come variabili.
Alcuni esempi di costanti sono:
77 /* un numero intero */ .0004 /* corrisponde a 0,0004 */ 1.2e6 /* notazione scientifica (1,2 * 10^6) */ 42nd /* non è un numero ma una costante */Il simbolo 42nd (quarantaduesimo in inglese) pur non essendo un numero è una costante valida il cui valore corrisponde sempre a 42ND. Tutti i numeri validi sono costanti, ma non tutte le costanti sono numeri validi.
Una speciale classe di simboli, in cui variabili e costanti sono combinate insieme per creare dei gruppi di variabili logicamente correlate, è costituita dai simboli composti. Una variabile contenente un punto viene trattata come un simbolo composto.
Alcuni esempi di validi simboli composti sono:
file.3 riga.colonna array.d.gI simboli composti possono essere utili per creare degli insiemi di variabili che possono venire elaborate in base al loro nome composito.
mese.1 = "gennaio" mese.2 = "febbraio" ... ... mese.12 = "dicembre"se in un programma usiamo la variabile corrente, assegnando ad essa un valore compreso tra 1 e 12 dalla variabile composta mese.corrente potremo ottenere il nome del mese corrispondente.
/* mese.cmd */ mese.1 = "gennaio" mese.2 = "febbraio" mese.3 = "marzo" mese.4 = "aprile" mese.5 = "maggio" mese.6 = "giugno" mese.7 = "luglio" mese.8 = "agosto" mese.9 = "settembre" mese.10 = "ottobre" mese.11 = "novembre" mese.12 = "dicembre" say "Immettere un numero compreso da 1 a 12 per avere il nome del mese..." pull corrente say "Al numero" corrente "corrisponde" mese.correnteUsando dei loop cioè dei comandi che permettono di ripetere più volte una serie di istruzioni, che vedremo più approfonditamente in seguito, possiamo elencare tutti i valori memorizzati in modo molto semplice.
/* lista.cmd */ mese.1 = "gennaio" mese.2 = "febbraio" mese.3 = "marzo" mese.4 = "aprile" mese.5 = "maggio" mese.6 = "giugno" mese.7 = "luglio" mese.8 = "agosto" mese.9 = "settembre" mese.10 = "ottobre" mese.11 = "novembre" mese.12 = "dicembre" do i = 1 to 12 /* ripete 12 volte */ say "mese" i "=" mese.i endCome vedremo poi, è pratica comune memorizzare il numero totale delle variabili nell'elemento 0:
/* lista_1.cmd */ mese.0 = 12 mese.1 = "gennaio" mese.2 = "febbraio" mese.3 = "marzo" mese.4 = "aprile" mese.5 = "maggio" mese.6 = "giugno" mese.7 = "luglio" mese.8 = "agosto" mese.9 = "settembre" mese.10 = "ottobre" mese.11 = "novembre" mese.12 = "dicembre" do i = 1 to mese.0 say "mese" i "=" mese.i end
La prima parte di un simbolo composto, incluso il punto, viene detta stem. Lo stem è seguito da una o più parti, costanti o variabili, separate da un punto che vengono dette tail.
L'insieme delle variabili accomunate da un unico stem viene detto array.
Lo stem può essere usato anche per riferirirsi contemporaneamente a tutte le variabili parte dell'array, inizializzandole, per esempio ad un dato valore:
punti. = 0in questo modo tutte le singole variabili, parti dell'array punti avrebbero il valore 0, cioè punti.0 = 0, punti.1 = 0, punti.2 = 0, ecc.
Come abbiamo appena affermato lo stem può essere seguito da una o più tail creando così array a più dimensioni.
Nel caso volessimo creare un gioco basato su una scacchiera, per esempio il gioco della dama, un array bidimensionale sarebbe utile per identificare le singole caselle. Definendo le pedine bianche con "b", le dame bianche con "B", le pedine nere con "n" e le dame con "N", la scacchiera potrebbe essere inizializzata come segue:
/* dama.cmd */ /* inizializza tutti gli elementi al valore di una stringa vuota */ board. = "" /* posiziona le pedine */ do col = 1 by 2 to 7 board.1.col = "b" end do col = 2 by 2 to 8 board.2.col = "b" end do col = 1 by 2 to 7 board.3.col = "b" end do col = 2 by 2 to 8 board.6.col = "n" end do col = 1 by 2 to 7 board.7.col = "n" end do col = 2 by 2 to 8 board.8.col = "n" end
Nel REXX ci sono 3 variabili speciali cui viene automaticamente assegnato un valore:
Spesso può essere necessario controllare che il nome di un simbolo non sia già stato usato per definire un'altra variabile. A questo scopo si usa la funzione Symbol() con il nome che si vuole controllare come parametro.
Il valore restituito da Symbol può essere:
/* SYMBOL.CMD */ alfa = 11 say "Symbol(""alfa"") =" Symbol("alfa") /* variabile inizializzata */ say "Symbol(""beta"") =" Symbol("beta") /* variabile non inizializzata */ say "Symbol(""33"") =" Symbol("33") /* costante */ say "Symbol("")&#@"") =" Symbol(")&#@") /* simbolo non valido */Un uso di Symbol() è quello di assicurarsi che una variabile sia stata inizializzata prima di impiegarla in un'operazione:
/* SYMBOL1.CMD */ if Symbol("cash") = LIT then cash = 0 cash = cash + 100 say "cash = "cashPerché il risultato ottenuto dalla funzione Symbol() possa essere considerato valido è indispensabile racchiudere tra virgolette il nome del simbolo che si vuole controllare. Se si omettessero le virgolette l'interprete REXX sostituirebbe al nome del simbolo il valore corrispondente.
Quando si scrive una subroutine di un programma complesso può capitare di non ricordarsi i nomi di tutte le variabili precedentemente usate. E' sempre possibile rileggersi tutto il codice precedentemente scritto, ma oltre al tempo sprecato si correrebbe il rischio di lasciarsi sfuggire qualche variabile. Con l'istruzione procedure è possibile usare nella subroutine nomi di variabili già usate in precedenza, con la sicurezza che queste vengano interpretate come variabili differenti.
L'istruzione procedure può essere usata solo come prima istruzione di una subroutine interna.
/* PROCED.CMD */ count = 999 alfa = 123456 list = 3 4 5 6 7 say "inizialmente count =" count say "inizialmente alfa =" alfa say "inizialmente list =" list call average list /* chiama la subroutine "average" */ say "nella procedura principale count =" count say "nella procedura principale alfa =" alfa say "nella procedura principale list =" list exit /* termina il programma */ /* questa è la subroutine "average" */ average: procedure arg a b c d e /* count è una variabile differente dal precedente count */ count = (a + b + c + d + e) / 5 alfa = 654321 say "nella routine ""average"" count =" count say "nella routine ""average"" alfa =" alfa say "nella routine ""average"" list =" list returnNel caso sia necessario esporre nella soubroutine alcune delle variabili esterne, si può aggiungere l'istruzione expose a procedure facendola seguire dalla lista delle variabili da esporre:
procedure expose nomevarabile_1 nomevariabile_2 ... nomevariabile_nPer capire meglio il funzionamento di procedure e expose può essere utile modificare più volte proced.cmd cancellando l'istruzione procedure o sostituendola con procedure expose seguita dal nome di una o più variabili.
Altri mezzi di memorizzazione dati
Le variabili sono il mezzo principale di memorizzazione e manipolazione dei dati all'interno di un programma REXX. Altri sistemi che permettono di condividere dati con altri programmi sono le code (queues) e i file.
In una delle seguenti lezioni vedremo come interagire sia con le queue che con i file.