[Generale] Perl e strutture dati multidimensionali

Szymon Stefanek pragma a siena.linux.it
Mer 22 Nov 2006 19:51:42 GMT


On Wednesday 22 November 2006 15:16, Alex M4DC4T wrote:
> In questi giorni mi sto' facendo una cultura su Perl. Sono arrivato a
> studiare le strutture di dati multidimensionali (implementabili tramite le
> references). Purtroppo non e' che ho capito benissimo, e il testo si
> dilunga poco.
> Richiesta:
> c'e' qualche anima pia che ha tempo da perdere (il meno possibile, ovvio)
> che mi puo' dare una mano a parole?

Premesso il fatto che è un topic da "tecnica" e tra un pò ci cacciano
da qui ecco la risposta :D

Dal punto di vista di strutture multidimensionali il libro (e il perl)
ti complica la vita. Prima di tutti sappi che PUOI usare una sintassi
come:

	$pippo[10][3] = 5;
	print $pippo[10][3];

Questa sintassi manipola un array multidimensionale (in particolare a due 
dimensioni).
Lo stesso si può fare per i hash

	$hash{"test"}{"prova"} = 5;
	print $hash{"test"}{"prova"};

Se ti basta fare questo non leggere oltre: fermati e vivi felice.

Se sei curioso di cosa succede sotto allora eccoti una spiegazione.

Il perl di base NON supporta strutture dati multidimensionali.
Se vuoi, è un suo difetto (anche se ci si può girare tranquillamente intorno).

In sostanza il perl manegga i seguenti tipi di dati:

- scalari (un numero, una stringa)
- array ad una dimensione di _scalari_ (quindi array di numeri o di stringhe)
- hash ad una dimensione di _scalari_ (quindi array di numeri o di stringhe)

Questo significa che un array multidimensionale non lo puoi fare
e non puoi fare nemmeno un "array di array".

...Che poi, fra parentesi, è interessante notare che in questo tipo di 
linguaggi un array multidimensionale e un array di array (di array...) NON 
sono la stessa cosa mentre in C, in generale, si... vabbeh.

Allora ecco la "magia" (o la menata, dipende da come la vedi) delle 
references.

Dato una variabile qualunque (scalare, array o hash), mediante una
particolare sintassi (__contorta__) si può ottenere un riferimento
ad essa, che per definizione è sempre scalare. Il reference è in sostanza una 
sorta di puntatore nascosto.

	perl -e '$scalare = 10; $ref = \$scalare; print $ref; print $$ref;'

Nota che nell'esempio sopra la sintassi $$ref fa il dereferenziamento.
Il '$' più interno accede al reference contenuto dentro la variabile $ref
mentre quello più esterno accede al contenuto della variabile referenziata.
Il doppio $, quindi, è l'operatore di dereferenziamento per scalari.

Questo significa che si può ottenere il reference di un array e dato
che il reference è scalare si può fare un array di reference ad array.

In sostanza si tratta di fare:

	$ausiliario[3] = 5;          # creo array "interno"
	$pippo[10] = \@ausiliario;   # all'array esterno assegno il reference
                                     # a quello interno: nota l'operatore
	                             # '\' che prende il reference di un array
	print $pippo[10]->[3];       # accedo tramite reference: nota
	                             # l'operatore '->' di dereferencing
                                     # per array e hash

Quindi l'array esterno è un array di references e l'array interno è
"puntato" dagli elementi di quello interno.

            0   1   2   3   4   5   6   7   8   9   10
  @pippo = | ? | ? | ? | ? | ? | ? | ? | ? | ? | ? |ref|
                                                     |
         +-------------------------------------------+
         |
         |       0   1   2   3
  @ausiliario = | ? | ? | ? | 5 |


Poi, per rendere le cose usabili ai comuni mortali, la sintassi
$pippo[10][20] è uno shortcut sintattico per scrivere la roba esposta sopra.


	man perlref

	http://www.ifarm.nl/erikt/perl/ln05.html

-- 

Szymon Stefanek

------------------------------------------------------------------------------
-
- Segmentation fault. Brain dumped.
-
------------------------------------------------------------------------------
-------------- parte successiva --------------
Un allegato non testuale è stato rimosso....
Nome:        non disponibile
Tipo:        application/pgp-signature
Dimensione:  189 bytes
Descrizione: non disponibile
Url:         http://liste.siena.linux.it/pipermail/generale/attachments/20061122/6dede00a/attachment.pgp


Maggiori informazioni sulla lista Generale