|
Le variabili non richiedono di essere dichiarate: vengono create
quando vengono utilizzate. Possiamo avere variabili di tre tipi:
scalari, array di scalari e array associativi di scalari. Le variabili
scalari hanno un nome che inizia per "$", le variabili array iniziano
per "@" mentre le variabili array associativi iniziano per "%". I
valori scalari sono sostanzialmente stringhe, comunque vengono
intepretate come numeri in base al contesto. Il Perl 5 prevede anche
che i valori scalari possano essere puntatori ad altri oggetti (sempre
scalari, array o array associativi). Molte variabili hanno un
significato speciale: per esempio la variabile $_ viene utilizzata da
accumulatore ed è assunta come default da molti comandi.
Il Perl ha un'ottima gestione degli array, che sono molto flessibili:
gli elementi di un array sono scalari e il loro contenuto può essere
un numero, una stringa o un puntatore a seconda dei casi. Gli array
possono essere manipolati in molti modi: possono essere allungati,
accorciati, scomposti e ricomposti a volontà. In pratica sostituiscono
a tutti gli effetti i record, che non esistono in Perl. Il Perl ha
molte funzioni corrispondenti a funzioni che in C restituiscono delle
struct. Queste funzioni in Perl restituiscono un array in cui ogni
elemento ha un significato diverso. Per esempio con:
@a = stat($filename)
si ottiene una informazione diversa in ogni elemento di @a: il
secondo elemento contiene gli attributi del file, mentre il settimo la
dimensione. Posso anche assegnare un array anonimo:
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size) = stat($filename)
Siccome ogni variabile viene inserita nell'array per riferimento,
l'assegnamento dell'array anonimo all'output della stat comporta
l'assegnamento di ognuna delle variabili. Una osservazione importante:
per riferirsi al settimo elemento di un array si usa la sintassi $a[7]
e non, come forse ci si aspetterebbe, @a[7]: in un certo senso, il $ è
come un articolo che significa "il", mentre @ significa "gli".
Per essere precisi in Perl ci sono due contesti: singolare e
plurale. Il contesto singolare si ha quando si assegna ad uno scalare
e il contesto plurale si ha quando si assegna ad un array o ad un
array associativo. Molti comando ed espressioni si comportano in
maniera diversa quando vengono invocati in contesti diversi. Per
esempio è possibile leggere un intero file e assegnare ogni riga ad un
elemento di un array con una sola istruzione. Ecco un programma che
stampa le righe in input in ordine inverso:
@a=<STDIN> print while defined($_= pop(@a)); |
Si legge un file usando un cosiddetto filehandle tra parentesi
angolate: in questo caso STDIN, che è aperto di default sullo standard
input - i filehandle sui file vanno aperti con open. L'intero
standard input viene letto e ogni elemento dell'array contiene una
riga dell'input originale. Il ciclo di stampa legge una riga caricando
nella variabile $_ l'ultimo elemento dell'array e accorciandolo. La
variabile risulta definita finchè ci sono elementi nell'array. Infine
la print (e moltissimi altri comandi) assume come argomento default la
variabile $_.
Da notare che se invece scriviamo
$_=<STDIN>
questo comporta la lettura di UNA SOLA riga dallo standard
input. Questo perchè l'assegnamento ad uno scalare comporta un
contesto singolare.
L'ultimo tipo di dato fondamentale sono gli array associativi, detti
anche hash: essi sono degli array che invece di essere indicizzati da
dei numeri sono indicizzati con degli scalari qualsiasi. Sono molto
potenti ed utili, ed hanno infiniti usi: come esempio scriviamo
programma che conta le occorrenze delle parole in input (si usano
anche delle espressioni regolari per "pulire" l'input, che saranno
spiegate più avanti)
| while(<STDIN>) { |
|
s/[^a-zA-Z]/ /g; tr/[A-Z]/[a-z]/; foreach(split) { ++$a{$_} } |
} foreach (keys %a) { |
|
printf "%6d $_\n", $a{$_}; |
| } |
Questo codice dovrebbe illustrare abbastanza la potenza e la
sinteticità del Perl. Innanzitutto si usa molto la variabile di
default $_: il while(<STDIN>) assegna implicitamente a $_ ogni riga
letta, lo split suddivide il contenuto della variabile $_ in un array
di stringhe separate da blank, il foreach cicla su un array e assegna
ogni elemento sempre a $_. Si nota che l'indicizzazione di un hash
viene effettuata utilizzando le parentesi graffe.
I comandi che cominciano con "s/" e "tr/" eliminano i caratteri non
alfabetici e convertono in minuscolo tutte le lettere maiuscole. Sono
rispettivamente operatori di sostituzione e traslazione, che
utilizzano espressioni regolari. Naturalmente modificano il contenuto
di $_. Osserviamo anche la cosiddetta interpolazione di stringhe: le
variabili incorporate nelle stringhe (sequenze di caratteri racchiuse
in doppi apici) vengono espanse quando si valuta la stringa.
Citiamo infine che è possibile trattare una tabella di database come
un array associativo: si può infatti "legare" (tie) tale tabella ad un
array associativo e estrarre i record dalla tabella utilizzando le
chiavi come fossero indici dell'hash a cui si è legata la tabella.
|