Sei sulla pagina 1di 7

Flavio Poletti

Matrici in Perl
http://www.perl.it/documenti/articoli/2007/11/matrici-in-perl.html
Se uno d un'occhiata rapida al manuale (in particolare perlvar), scopre un'interessante verit circa
i principali tipi di variabili in Perl:
scalari: possono contenere un valore singolo, di varia natura (come un numero, o una
stringa);
array: sono delle collezioni ordinate di elementi - elementi scalari;
hash: sono delle associazioni fra stringhe (dette chiavi) e valori, i quali sono, nuovamente,
degli scalari.
Cos, di primo acchito, verrebbe da dire che non ci sia molto per sbizzarrirsi. O valori singoli,
oppure insiemi che contengono valori singoli. Ma allora una matrice come la rappresentiamo?!?
Come facciamo ad aggiungere dimensioni ad un semplice array?

Riferimenti alla riscossa


La chiave per la creazione di strutture multilivello in Perl sta nel comprendere un semplicissimo
dato di fatto: un riferimento uno scalare.
L'avete assorbita o siete svenuti? Vedo che alcuni hanno un bagliore intorno alla testa: o sono
divenuti santi (cosa di cui dubito, vista la gentaccia che frequenta perl.it), oppure si accesa la
fatidica lampadina. Per altri, al contrario, l'unica cosa che illumina il buio quel grosso, splendente
punto interrogativo. Vediamo di mandarlo via.
Un riferimento come un'etichetta che vi dice come trovare qualcosa. Una specie di nota che vi
scrivete da una parte, e vi dice dove trovare l'oggetto cui ci si riferisce. Immaginate di avere
tantissimi CD, ad esempio, e di volerne mantenere sempre il controllo. Va da s: accendete il PC,
lanciate un editor e cominciate a scrivere un programma in Perl. Nel programma, per, non potete
infilare fisicamente il disco; usate allora qualcosa che rappresenta il disco, e che in qualche modo
vi consente di ritrovarlo in mezzo a tutti gli altri.
Se avete una qualsiasi variabile, potete prendere un riferimento ad essa in maniera molto rapida:
basta mettere un carattere backslash (ossia il carattere "\") immediatamente prima della variabile,
come ad esempio:
my $rif_a_scalare = \$scalare;
my $rif_a_array
= \@array;
my $rif_a_hash
= \%hash;

Un esempio lo trovate nella figura AoA00-reference.png.


Perl Mongers Italia. Tutti i diritti riservati.

1 of 7

Flavio Poletti

Matrici in Perl
http://www.perl.it/documenti/articoli/2007/11/matrici-in-perl.html
Se invece avete un riferimento, e volete ritornare all'oggetto puntato, occorrer effettuare la
cosiddetta dereferenziazione. Il modo universale per dereferenziare un qualsiasi riferimento
derivante da un'espressione mediante le parentesi graffe. Supponiamo ad esempio di avere:
my $rif_a_array = \@array;

e di voler "tornare" all'array; il modo pi generale per farlo con:


my @copia_di_array = @{ $rif_a_array };

Le graffe racchiudono l'espressione che restituisce il riferimento all'array; il sigillo che si trova
immediatamente prima (ossia il carattere @ nel nostro caso) ci dice cosa ci stiamo aspettando
dall'operazione di dereferenziazione - un array nel nostro caso.
Esiste anche una versione light che funziona quando il riferimento contenuto in una variabile:
my @copia_di_array = @$rif_a_array;

In pratica, in questi casi semplificati cadono le graffe.

Creare i riferimenti ad array


Come abbiamo visto, dato un array possiamo creare un riferimento ad esso utilizzando il
backslash:
my $rif_a_array = \@array;

Questo, per, ci costringe ad avere un array da cui partire! Se non vogliamo passare da un array
esistente, ma costruire un array "al volo" e farci dare un riferimento ad esso, possiamo utilizzare il
costruttore di array anonimi:
my $rif_a_array_anonimo = [ 'ciao', 'a', 'tutti' ];

Una coppia di parentesi quadre ed il gioco fatto! Ovviamente possiamo partire da un array vuoto:
my $rif_a_array_vuoto = [ ];

oppure dalla copia di un altro array:


my $rif_a_copia_di_array = [ @array ];

Insomma: tutto quello che si trova nelle parentesi quadre viene espanso come una lista e copiato
nell'array anonimo. Il costruttore (ossia, la coppia di parentesi quadre) restituisce un riferimento a
questo array, che in tal modo non ha necessit di avere un nome tutto per s.
Perl Mongers Italia. Tutti i diritti riservati.

2 of 7

Flavio Poletti

Matrici in Perl
http://www.perl.it/documenti/articoli/2007/11/matrici-in-perl.html

Usare i riferimenti ad array


Quando avete un riferimento ad array potete usarlo quasi come se aveste direttamente l'array
stesso. Solamente che dovete ricordarvi di avere in mano un fogliettino, non il CD! Per questo
motivo, se con un array in carne ed ossa scriveremmo:
my $terzo_elemento = $array[2];

per accedere al terzo elemento, con un riferimento dobbiamo aggiungere una freccetta per
indicare la dereferenziazione:
my $terzo_elemento = $rif_a_array->[2];

Ovviamente avevamo gi visto come dereferenziare, per cui potremmo scrivere anche:
my $terzo_elemento = ${ $rif_a_array }[2];

ma che obbrobbrio! Converrete con me che molto meglio la freccetta!

Ok, e le strutture multilivello?


In realt, ora si tratta solo di mettere insieme i pezzi.
Abbiamo detto che un array, ad esempio, pu contenere solamente scalari. Un array con altri array
dentro, dunque, non fattibile. Qui per i riferimenti ci vengono in aiuto: poich questi sono degli
scalari, infatti, possono andare tranquillamente ad occupare posizioni in un array. L'idea che
nell'array esterno (il contenitore) ci mettiamo dei riferimenti ai sotto-array invece dei sotto-array
stessi.
La figura AoA01-bare.png mostra questa idea al lavoro mentre viene costruita una matrice a due
dimensioni.
Prima di tutto, osserviamo che la struttura disegnata rispetta le regole poste; la figura AoA03-tuttiscalari.png, infatti, rende chiaro come tutti gli elementi dei vari array in gioco siano degli scalari.
L'array originale (figura AoA05-array-1.png), per, invece di contenere scalari "tradizionali" (come
stringhe e numeri) contiene dei riferimenti ad altri array (quelli in figura AoA06-array-2.png).
La figura AoA07-dressed.png riassume quanto abbiamo detto: in verde sono riportati gli array, in
blu gli scalari "normali" ed in rosso i riferimenti.

Perl Mongers Italia. Tutti i diritti riservati.

3 of 7

Flavio Poletti

Matrici in Perl
http://www.perl.it/documenti/articoli/2007/11/matrici-in-perl.html
Proviamo allora a definire con il codice Perl quello che abbiamo rappresentato graficamente:
my @array;
for my $riga ( 0 .. 4 ) {
my @sotto_array = 1 .. 6; # Qualche dato nella riga
# Infiliamo il sotto-array in @array. Ovviamente non infiliamo
# direttamente @sotto_array, ma un riferimento
push @array, \@sotto_array; # Notare il backslash "\"
}
my $rif_a_array = \@array;

Abbiamo che:
@array quello di figura AoA05-array-1.png;
i vari @sotto_array creati durante il ciclo sono quelli indicati in figura AoA06-array-2. Da
notare che ad ogni iterazione del ciclo viene creato un nuovo @sotto_array, poich viene
specificato con my all'interno del blocco di for;
la variabile $rif_a_array quella indicata in figura AoA02-scalare.png.
Proviamo ad utilizzare la struttura, dunque:
il secondo elemento di @array (v. figura AoA08-secondo.png) accessibile come
$array[1] oppure, come abbiamo visto, come $rif_a_array->[1];
l'array puntato da quest'ultimo accessibile nelle seguenti maniere:
my @copia_secondo_array = @{ $array[1] };
my @altra_copia_secondo = @{ $rif_a_array->[1] };
e il terzo elemento della quarta riga (figura AoA09-43.png)? Facile:
il riferimento alla quarta riga, lo sappiamo gi, dato da $array[3] o, indifferentemente,
da $rif_a_array->[3];
di conseguenza, per accedere al terzo elemento dell'array puntato da questo riferimento
possiamo scrivere:
my $elem_4_3
= $array[3]->[2]; # Oppure
my $elem_4_3_bis = $rif_a_array->[3]->[2];
In Perl, ve ne sarete accorti, quando si hanno cose lunghe e noiose da scrivere di solito esiste una
scorciatoia. Questo caso non fa eccezioni: per evitare la festa delle frecce, infatti, possibile
evitare di mettere le frecce quando queste andrebbero poste fra due gruppi di parentesi. A farla
Perl Mongers Italia. Tutti i diritti riservati.

4 of 7

Flavio Poletti

Matrici in Perl
http://www.perl.it/documenti/articoli/2007/11/matrici-in-perl.html
breve, dunque, possiamo scrivere:
my $elem_4_3_ter
= $array[3][2]; # Oppure
my $elem_4_3_quater = $rif_a_array->[3][2];

Da notare che, in $elem_4_3_quater, la prima freccia non posta fra due gruppi di parentesi,
per cui non possiamo ometterla.

Trovare le dimensioni
Trovare le dimensioni di una matrice in Perl piuttosto semplice, basta ricordare che la valutazione
di un array in contesto scalare restituisce il numero dei suoi elementi.
Eh?
Procediamo con un esempio, che sempre meglio:
my @primi = ( 2, 3, 5, 7, 11, 13 );
my $conteggio = @primi;

Quanto varr conteggio? Beh, deriva dalla valutazione di un array (@primi) in contesto scalare
(per via dell'assegnazione allo scalare $conteggio stesso), per cui il valore pari a 6. Ossia, il
numero di elementi di @primi.
Se ora torniamo alla nostra matrice, notiamo che:
1. il numero di righe pari al numero di elementi di @array (v. AoA05-array-1.png);
2. il numero di colonne pari al numero di elementi di una qualsiasi delle righe, ad esempio
$array[0] (v. AoA06-array-2.png). Questo presuppone, ovviamente, che si abbia a che
fare con una matrice vera, in cui tutte le righe hanno la stessa lunghezza.
Non deve stupire allora che il numero di righe sia calcolabile piuttosto rapidamente:
my $numero_righe
= @array;
my $numero_righe_alternativo = @$rif_a_array;

e che anche il numero di colonne non riservi particolari sorprese:


my $numero_colonne
= @{ $array[0] };
my $numero_colonne_alternativo = @{ $rif_a_array->[0] };

Se proprio non vi piace utilizzare troppe parentesi, potete passare per una variabile intermedia:
my $rif_prima_riga = $array[0]; # oppure:
Perl Mongers Italia. Tutti i diritti riservati.

5 of 7

= $rif_a_array->[0];

Flavio Poletti

Matrici in Perl
http://www.perl.it/documenti/articoli/2007/11/matrici-in-perl.html
my $numero_colonne_alt2 = @$rif_prima_riga;

In ogni caso, mettela un po' come vi pare: l'importante che valutiate l'array giusto in contesto
scalare!

Conclusioni
Buone notizie, dunque: non solo possiamo fare strutture multilivello (qui ci siamo fermati a due,
ma lo stesso discorso si pu ripetere al livello che si vuole), ma l'accesso ai vari elementi anche
piuttosto intuitivo, poich richiede che gli indici delle varie dimensioni siano posti ciascuno dentro
un paio di parentesi quadre.
Queste matrici in Perl hanno un nome particolare: AoA, ossia Array Of Array, array di array. Il
nome deriva da questo modo un po' bizzarro con cui sono costruite, ma formalmente impreciso
perch ricordate: un array pu contenere solamente scalari!
Come spesso succede con un tutorial, siete a poco pi dell'inizio. Il che non vuol dire che siete
messi male, al contrario: potete gi sbizzarrirvi a costruire strutture multilivello ed a sbatterci
contro la testa. Per non farvi troppo male... utilizzate il modulo Data::Dumper per stampare le
strutture: potreste scoprire che non tutto come vorreste che sia, ma almeno saprete dove
mettere le mani!
Per proseguire si consiglia di guardare la seguente documentazione.

perldata
Doverosa una tappa. Spiega tutto quello che dovete sapere sui tipi di dato in Perl!

perlref
I riferimenti giocano un ruolo fondamentale nella costruzione delle strutture multilivello.
Leggere perlref significa riempire la faretra con le frecce giuste (esatto! le frecce per la
dereferenziazione!).

perllol
No, non sono un sacco di risate, ma un modo improprio di definire gli AoA in termini di List
Of Lists. Il tutorial presuppone la conoscenza di riferimenti e simili, ma con quello che avete
letto qui dovreste cavarvela.
Perl Mongers Italia. Tutti i diritti riservati.

6 of 7

Flavio Poletti

Matrici in Perl
http://www.perl.it/documenti/articoli/2007/11/matrici-in-perl.html
perldsc
Meglio noto come Perl Data Structure Cookbook, ossia il ricettario Perl per le strutture dati.
Oltre agli AoA vengono trattate altre strutture multilivello, in particolare quelle che
coinvolgono le hash. Da non perdere!
Perl Mongers Italia. Tutti i diritti riservati.

7 of 7