Telemat Lab's home page


Copyrigtht © 2000 Universita' di Firenze. All rights reserved.

Free license available.

 

Moduli e Oggetti in Perl

Package e Moduli in Perl

A cura di: David Cristofani

Revisori: Prof. Franco Pirri  , Ing. Claudio Bizzarri 


Package e Moduli in Perl

HYPER HOME Indice gen. Indice prec. Indice attuale Indice succ.

 

Indice generale
Indice lezione corrente
Slide successiva
Testo
slide 1
Slide 1/7

Da quanto esposto nella slide si può ricavare che quando scriviamo qualcosa del tipo:


$nome = "Topolino";
@nomi_vet = ("Pippo", "Pluto");
print "$nome\n";
print "@nomi_vet\n";

questo è perfettamente equivalente a:


$main::nome = "Topolino";
@main::nomi_vet = ("Pippo", "Pluto");
print "$main::nome\n";
print "@main::nomi_vet\n";

In pratica $main::nome e @main::nomi_vet rappresentano i nomi estesi di $nome e di $nomi_vet (come si vede nel nome esteso di una variabile è presente anche l'indicazione dello spazio di nomi a cui questa appartiene).
Tuttavia, poichè in uno spazio di nomi non è necessario utilizzare il nome esteso per identificare le variabili che appartengono allo spazio di nomi stesso, la prima delle due forme sopra riportate risulta più conveniente.

Slide successiva Slide precedente

 

 

 

 

Indice generale
Indice lezione corrente
Slide iniziale
Slide precedente
Slide successiva
Testo
slide 2
Slide 2/7

Consideriamo il seguente esempio:


$nome = "Topolino";
print "$nome\n";

package paperi;

$nome ="Paperino";
print "$nome\n";
print "$main::nome\n";

L'esecuzione di questo programma causa la stampa a video del seguente output:

Topolino
Paperino
Topolino

Cerchiamo di analizzare nel dettaglio questo esempio.
Come si può vedere nel programma sono presenti due spazi di nomi: il primo (non essendo espressamente definito) coincide con quello di default (cioè main::) mentre il secondo, definito attraverso la direttiva package, si chiama paperi::.
In questo modo si ha che la variabile $nome definita nello spazio main:: e la variabile $nome definita nello spazio paperi:: costituiscono due entità distinte (ovvero appartengono a due tavole dei simboli diverse).
Il fatto che tali variabili siano due entità distinte risulta più evidente se consideriamo i loro nomi estesi che sono dati rispettivamente da $main::nome e $paperi::nome.
Si può inoltre osservare che, proprio tramite l'uso del nome esteso, si è potuto fare riferimento alla variabile $main::nome all'interno dello spazio di nomi paperi::.

Slide successiva Slide precedente

 

 

 

 

Indice generale
Indice lezione corrente
Slide iniziale
Slide precedente
Slide successiva
Testo
slide 3
Slide 3/7

Cerchiamo di chiarire meglio i punti precedenti tramite un esempio:


package somma;
$num1 = 10;
$num2 = 20;

package sottrazione;
$num1 = 40;
$num2 = 30;
$sub = $num1 - $num2;
$somma::sum = $somma::num1 + $somma::num2;

package somma;
print "$sum\n";
print "$sottrazione::sub\n";

Oltre a quanto riportato nella slide, questo esempio mette in evidenza anche i seguenti fatti:

Slide successiva Slide precedente

 

 

 

 

Indice generale
Indice lezione corrente
Slide iniziale
Slide precedente
Slide successiva
Testo
slide 4
Slide 4/7

Nella slide precedente avevamo affermato che un file può contenere più package; tuttavia, nella pratica, è consuetudine avere un solo package all'interno di un file.
In effetti questo è anche il modo in cui normalmente si realizzano librerie di funzioni in Perl.
Supponiamo ad esempio di voler realizzare una libreria di funzioni statistiche e di memorizzarla in un file di nome statistica.pl (per semplicità considereremo soltanto l'implementazione di una funzione per il calcolo della media aritmetica dei numeri contenuti nel vettore che le viene passato come argomento):


#--------------- statistica.pl ---------------#
package stat;

sub media
{
  my $somma = 0;
  foreach $num (@_)
    {
     $somma += $num;
    }
  return ($somma/@_);
}

1;

Per poter utilizzare una libreria all'interno di un altro file occorre richiamarla tramite la funzione require nella forma require "nome_file".
Ovviamente per poter utilizzare le variabili globali presenti in una libreria o per richiamare le funzioni in essa definite occorre utilizzare i loro nomi estesi (questo perchè appartengono ad un package e quindi ad uno spazio di nomi ben definito).
Un esempio di utilizzo della libreria statistica.pl può essere il seguente:

require "statistica.pl";

@valori = (10, 34, 15, 56, 43);
$val_medio = stat::media(@valori);
print "$val_medio\n";

Entrando più nel dettaglio le caratteristiche della funzione require sono le seguenti:

Slide successiva Slide precedente

 

 

 

 

Indice generale
Indice lezione corrente
Slide iniziale
Slide precedente
Slide successiva
Testo
slide 5
Slide 5/7

I moduli forniscono un metodo alternativo per realizzare librerie di funzioni.
Per trasformare ad esempio la libreria creata in precedenza in un modulo è sufficiente rinominare il file statistica.pl in stat.pm


#--------------- stat.pm ---------------#
package stat

....
La differenza più importante tra librerie e moduli, oltre a quelle riportate nella slide, risiede nel modo in cui questi vengono importati.
Un modulo viene importato tramite la funzione use nella forma use nome_modulo

use stat;

....
Le caratteristiche della funzione use sono le seguenti:

Slide successiva Slide precedente

 

 

 

 

Indice generale
Indice lezione corrente
Slide iniziale
Slide precedente
Slide successiva
Testo
slide 6
Slide 6/7

Un modulo che voglia offrire la possibilità di esportare nomi di variabili e di funzioni definite al suo interno deve presentare la seguente struttura:


#--------------- nome_modulo.pm ---------------#
package nome_modulo;
use Exporter;
@ISA = qw(Exporter);

@EXPORT = qw(...);    #lista dei simboli che devono essere esportati di default
@EXPORT_OK = qw(...); #lista dei simboli da esportare su richiesta

....
....
Analizziamo nel dettaglio quanto sopra riportato: In maniera analoga nel package che vuole importare il modulo nome_modulo deve essere presente una tra le seguenti tre istruzioni:

use nome_modulo;          #importa nel package i simboli di default

use nome_modulo qw(...);  #importa nel package i simboli specificati nella lista

use nome_modulo();        #non importa nel package alcun simbolo

Cerchiamo di chiarire e riassumere il tutto riprendendo in considerazione l'esempio della libreria di funzioni statistiche:

#--------------- stat.pm ---------------#
package stat;
use Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(media);

sub media
{
 my $somma = 0;
 foreach $num (@_)
   {
    $somma += $num;
   }
 return ($somma/@_);
}

1;

In questo modo il modulo stat esporta su richiesta la funzione media e può essere utilizzato nel modo seguente:

use stat qw(media);

@valori = (10, 34, 15, 56, 43);
$val_medio = media(@valori);
print "$val_medio\n";

Come si vede, in questo caso, si può utilizzare la funzione media senza dover ricorrere al suo nome esteso come se questa fosse stata definita nel package da cui viene richiamata.

Slide successiva Slide precedente

 

 

 

 

Indice generale
Indice lezione corrente
Slide iniziale sezione successiva
Slide iniziale
Slide precedente
Testo
slide 7
Slide 7/7

Mostriamo con un semplice esempio uno dei possibili utilizzi di questa funzione.


#--------------- stat.pm ---------------#
package stat;
use Exporter;
@ISA = qw(Exporter);
@EXPORT_OK = qw(media);

sub media
{
 my $somma = 0;

 foreach $num (@_)
   {
    $somma += $num;
   }
 return ($somma/@_);
}

...

sub AUTOLOAD
{
 print "La funzione $AUTOLOAD non è stata implementata in questo modulo\n";
}

1;

In questo modo tutte le volte che si invoca una funzione del modulo stat che non è stata definita il programma non termina ma si limita ad avvertirci del fatto che tale funzione non è stata implementata.
Quando parleremo degli oggetti avremo modo di considerare un esempio più significativo.

Slide iniziale sezione successiva Slide precedente


Ultimo aggiornamento 5/12/2000.

Slide iniziale


Telemat Lab's home page

HYPER HOME Indice gen. Indice prec. Indice attuale Indice succ.