1. Parte 2
Programmazione modulare
in Perl
Linguaggi dinamici – A.A. 2009/2010
1
2. Introduzione
T Il primo passo verso una attività di
programmazione che scali con il numero di
righe di codice del software è l'isolamento
de e u o a tà del so t a e
delle funzionalità de software stesso
T Parti diverse del software
T “non si vedono” tra loro
T possono essere scritte indipendentemente da
programmatori diversi
di ersi
T possono essere cambiate concorrentemente
T Il Perl supporta la modularizzazione tramite i
package ed i moduli
Linguaggi dinamici – A.A. 2009/2010
2
3. Package
T Il package è un contenitore (namespace) di
simboli (funzioni, variabili)
(funzioni
T Tipicamente, ad un package corrisponde un file
(non è sempre così)
T Il compilatore del Perl costruisce un
namespace (contenitore di simboli) per
ciascun modulo
T Namespace di default: package main (
N d f lt k i (contiene
ti
le funzioni eseguite dal programma principale)
T Il package contiene un puntatore ad una
tabella dei simboli per il lookup di variabili,
funzioni, descrittori
Linguaggi dinamici – A.A. 2009/2010
3
4. Contenuto del package
T Ciascuna variabile non espressamente
dichiarata con my è una variabile globale al
package
T Tanto è vero che nel gergo del Perl non si
che, Perl,
parla di variabili globali, bensì di variabili di
package
T Lo scope di un package va:
T dalla dichiarazione del package
package nome_pacchetto;
T Alla fi d l bl
All fine del blocco di codice in cui è contenuta
di i i t t
tale direttiva (tipicamente, la fine del file)
Linguaggi dinamici – A.A. 2009/2010
4
5. Scope del package
T È possibile avere più (scope di) package nello
stesso file
T Anche ripetuti
T Esempio:
T package A;
T $a = 5;
T package B;
T print $A::a;
T package A;
T print $a;
Linguaggi dinamici – A.A. 2009/2010
5
6. Accesso ai simboli del package
T Il namespace assegnabile ad un package è una
sequenza di stringhe alfanumeriche separata
dal simbolo ::
T Time::Local, My::Package
Time::Local My::Package, Getopt::Long
T I simboli di un package possono essere
acceduti con la notazione completa:
T Path::to::package::symbol;
T Si prepende al nome in notazione completa il
simbolo della variabile
$((scalar), @ (array), % (h h) & ( b)
l ) ( ) (hash), (sub)
T Attenzione: use strict; richiede che le variabili
di package siano dichiarate tali con our
Linguaggi dinamici – A.A. 2009/2010
6
7. Denominazione dei package
T I nomi completi assegnati ai package non
vengono utilizzati per dedurre relazioni
esplicite (sottoclassi, altro)
T package Red;
T package Red::Blue;
T I due package Red e Red::Blue non sono i
d k R d R d Bl in
alcun modo collegati fra loro
T Si deve usare la notazione completa, sempre:
d l i l
T $Red::Blue::foo;
T Il package di default è main (o $)
T $::foo è equivalente a $main::foo
Linguaggi dinamici – A.A. 2009/2010
7
8. Un package speciale – main
T Il package main è speciale, nel senso che è
l unico
l'unico package a poter usufruire delle variabili
speciali (perldoc perlvar)
T $!: il valore della variabile errno (glibc)
T $?: stringa di errore riportata da programma
esterno
T $_: la variabile di default
T $/: t
$/ il terminatore di riga di default
i t i d f lt
T STDIN, STDOUT, STDERR: descrittori di file
associati al processo
T @ARGV: l'array degli argomenti
T %ENV: l'ambiente di shell
Linguaggi dinamici – A.A. 2009/2010
8
9. Tabella dei simboli
T L'insieme dei simboli (variabili, funzioni)
contenuti in un package è memorizzato nella
tabella dei simboli
T La tabella dei simboli è memorizzata in una
hash avente lo stesso nome del package,
terminato con ::
T %MyPackage::, %main::
T La tabella dei simboli non viene solitamente
acceduta direttamente dal programmatore
Linguaggi dinamici – A.A. 2009/2010
9
10. Lookup tabella dei simboli
T Quando si scrive print $foo; viene scatenata la
sequenza di operazioni riportata di seguito
T Il perl controlla se esiste una variabile lessicale
(my) di nome foo
T Se non esiste, si cerca il simbolo foo nella
tabella dei simboli del package attuale
Linguaggi dinamici – A.A. 2009/2010
10
11. Simboli con stesso nome e tipo diverso
T Si è detto che le tabelle dei simboli sono
implementate con delle hash
T Inoltre, variabili di tipo diverso possono avere
lo stesso nome:
T $foo, @foo, %foo
T Come fa la tabella dei simboli a differenziare
fra variabili di tipo diverso e stesso nome?
T Le hash devono avere chiavi univoche
Linguaggi dinamici – A.A. 2009/2010
11
12. Typeglob
T Tale problema si risolve con i typeglob
T Un typeglob (identificato con il simbolo *)
raggruppa tutti i simboli che hanno lo stesso
nome
T *foo rappresenta $foo (scalar), @foo (array),
%foo (hash), &f (function), f (fil h dl )
%f (h h) &foo (f ti ) foo (filehandle)
T *foo è una struttura dati contenente celle di
memoria per ciascuno dei simboli avente nome
i i d i i b li t
foo
Linguaggi dinamici – A.A. 2009/2010
12
13. Includere un file esterno
T È possibile includere il contenuto di un file
esterno con la funzione require
T Il successo dell’inclusione è dato dal valore
dell ultimo
dell’ultimo statement del file incluso
T Si usa terminare il file da includere con 1;
T require può accettare come parametro:
T Una stringa costante che rappresenta il nome
del file
T Una espressione che, valutata, rappresenta il
p , , pp
nome del file
T Un nome, che viene interpretato come modulo
, p
Linguaggi dinamici – A.A. 2009/2010
13
14. Modulo
T Il modulo è l'unità di base per il riuso di codice
T Un modulo è un package
T contenuto in un file che ha lo stesso nome del
package ( d il suffisso .pm)
k (ed ffi )
T che termina con l'espressione vera 1;
T Ad esempio: file Foo.pm
package Foo;
# sub, var, …
1;
Linguaggi dinamici – A.A. 2009/2010
14
15. Uso di un modulo
T Un programma Perl “usa” un modulo
specificandolo con la funzione use
T use Time::Local;
T È sufficiente il nome del modulo senza
modulo,
estensione .pm
T In questo modo è possibile utilizzare i simboli
(variabili, funzioni, …) nel programma (o
modulo) che lo usa
Linguaggi dinamici – A.A. 2009/2010
15
16. use vs. require
T use è molto più utilizzato rispetto a require
T Controlla l esistenza del modulo a tempo di
l’esistenza
compilazione
T Più flessibile nella gestione dei simboli
T Corrisponde a
T BEGIN { req ire Mod le Mod le >import( LIST ); }
require Module; Module->import( )
T Ma:
T use serve solo per i moduli ( (estensione .pm),
)
require per file (Perl) qualsiasi
T use non è parametrizzabile, non si può usare
ti bil i ò
una variabile (è eseguita a tempo di
compilazione)
Linguaggi dinamici – A.A. 2009/2010
16
17. Esportazione dei simboli
T Alcuni simboli possono essere esportati agli
altri moduli o programmi che ne faranno uso
T Un modulo non avrebbe molto senso, senza tali
simboli
T Tali simboli possono essere referenziati negli
altri moduli con la notazione breve (quella
solita, $foo, @foo, …)
T Si
S usa il modulo di base Exporter
T Implementa una funzione import appropriata
Linguaggi dinamici – A.A. 2009/2010
17
18. All'interno del modulo
T Si definisce il package
T Si importa il modulo Exporter
T require Exporter;
T Si fa diventare il nostro modulo una
sottoclasse di Exporter
T our @ISA = “Exporter”;
T Si definiscono le tipologie di oggetti da
esportare, all'interno di opportuni array
Linguaggi dinamici – A.A. 2009/2010
18
19. All'interno del modulo
T our @EXPORT: array di simboli sempre
esportati dal modulo
T our @EXPORT_OK: array di simboli esportati
su richiesta del modulo che importa
T our %EXPORT_TAGS: hash di chiavi che
rappresentano gruppi di simboli esportabili
t i i b li t bili
T I simboli devono apparire anche in EXPORT o
EXPORT_OK
Linguaggi dinamici – A.A. 2009/2010
19
20. All'esterno del modulo
T Il programma importa il modulo
T use Foo;
T Tutti i simboli esportati tramite @EXPORT sono
già visibili di tt
ià i ibili direttamente
t
T Il programma importa il modulo
T use Foo qw(simbolo1 simbolo2);
T Si richiede l‘importazione dei simboli simbolo1
p
e simbolo2
T Il programma importa il modulo
T use Foo qw(simbolo_inesistente);
T Errore: simbolo inesistente non esiste
simbolo_inesistente
Linguaggi dinamici – A.A. 2009/2010
20
21. All'esterno del modulo
T Il programma importa il modulo
T use Foo qw(:tag);
T Vengono importati tutti i simboli esportati
tramite la chiave t i @EXPORT_TAGS
t it l hi tag in @EXPORT TAGS
T Il programma importa il modulo
T use Foo qw(/pattern/);
T Vengono importati tutti i simboli che fanno
match con pattern (espressione regolare)
T È anche possibile chiedere di non importare un
p p
simbolo
T Uso dell’operatore !
dell operatore
Linguaggi dinamici – A.A. 2009/2010
21