Transcript 4-perl_2

Bioinformatica
Linguaggio Perl (2)
Dr. Giuseppe Pigola – [email protected]
Dr. Alessandro Laganà – [email protected]
Corrispondenza di pattern

Uno degli strumenti di PERL per riconoscere pattern sono le
espressioni regolari;

Le espressioni regolari sono quasi un linguaggio a parte;

Sono un metodo formale di descrivere i pattern da trovare;

Nel seguito vedremo come creare semplici espressioni regolari,
usare le espressioni regolari nella corrispondenza di pattern e
modificare le stringhe usando le espressioni regolari;
2
Bioinformatica
Pattern semplici
In PERL i pattern sono racchiusi in un operatore di corrispondenza di
pattern, che alle volte è rappresentato come m//:

m/Simon/

Il pattern precedente corrisponde alle lettere S-i-m-o-n in sequenza;

Se non specificato diversamente il pattern viene cercato in $_;

Se il pattern specificato da m// è trovato nella variabile $_, l’operatore di
corrispondenza restituisce vero:
if (m/Piglet/) {
:
# Il pattern “Piglet” è in $_
}
3
Bioinformatica
Metacaratteri

Nel pattern ogni carattere corrisponde a se stesso a meno che
non si tratti di un metacarattere;

I metacaratteri sono i caratteri che cambiano il comportamento
della corrispondenza di pattern:
 ^ $ ( ) \ | @ [ { ? .+ *

Se il pattern contiene un metacarattere da usare come valore
letterale, si deve far precedere il metacarattere da un backslash:
m/I won \$10 at the fair/; # Il carattere $ è trattato come
simbolo del dollaro letterale
4
Bioinformatica
// o altri delimitatori
Oltre che usando gli slash, è possibile rappresentare l’operatore
di corrispondenza utilizzando qualsiasi altro carattere:

if (m,Waldo,) { print “Found Waldo.\n”; }
Spesso il delimitatore viene sostituito quando il pattern contiene
slash:

if (m/\/usr\/local\/bin\/hangman/) { print “Found…”; }
Ma così è più leggibile:

if (m:/usr/local/bin/hangman:) { print “Found…”; }
5
Bioinformatica
Delimitatori // - Variabili

Se i delimitatori sono slash si può anche scrivere la
corrispondenza di pattern senza la m e scrivere ad es. /Cheetos/
al posto di m/Cheetos/;

Anche le variabili possono essere usate nelle espressioni regolari.
Se un’espressione regolare contiene una variabile scalare, PERL
valuta prima la variabile e la interpola; quindi esamina
l’espressione regolare:
$pat=<STDIN>; chomp $pat;
$_=“The phrase that pays”;
if (/$pat/) {
print “\”$_\” contains the pattern $pat\n”;
}
6
Bioinformatica
Regole del gioco…

Generalmente, le corrispondenze di pattern iniziano a sinistra della stringa
obiettivo e procedono verso destra;

Le corrispondenze di pattern restituiscono vero (in qualsiasi contesto) solo
se l’intero pattern è presente nella stringa obiettivo;

E’ trovata per prima la prima corrispondenza possibile (quella più a sinistra)
nella stringa obiettivo. Le espressioni regolari non lasciano indietro una
buona corrispondenza per cercarne un’altra;

Si prende la prima corrispondenza più grande possibile. L’espressione
regolare potrebbe trovare subito una corrispondenza e cercare di
estenderla il più possibile. Le espressioni regolari cercano di estendere
quanto più possibile la corrispondenza.
7
Bioinformatica
Un metacarattere semplice: .

Il metacarattere punto . corrisponde a qualsiasi carattere singolo
a eccezione del carattere di nuova riga;

Per es., nel pattern /p.t/, il punto corrisponde a qualsiasi carattere
singolo;

Questo pattern troverebbe corrispondenza in pot, pat, pit, carpet,
python, …
8
Bioinformatica
I non stampabili

\n
carattere di nuova riga;

\r
ritorno a capo;

\t
tabulazione;

\f
carattere di avanzamento di pagina;
9
Bioinformatica
Quantificatori

Un quantificatore è un tipo di metacarattere che indica
all’espressione regolare quante occorrenze consecutive di
qualcosa deve trovare;

Un quantificatore può essere inserito dopo qualsiasi carattere
singolo o gruppo di caratteri;

Il quantificatore più semplice è il metacarattere +, che fa sì che il
carattere precedente corrisponda almeno una volta. Quindi,
/do+g/ si trova in:
 hounddog
ma non in badge
 hotdog
ma non in doofus
 doogie howser
ma non in Doogie
 doooooog
ma non in pagoda
10
Bioinformatica
I metacaratteri * e ?

* è simile a +, ma fa sì che il carattere precedente corrisponda zero o più
volte;

Ad es. il pattern /t*/ indica di trovare quante più corrispondenze è possibile,
ma anche nessuna. Quindi /car*t/ corrisponde a:
 carted
ma non a carrot
 cat
ma non a carl
 carrrt
ma non a caart

Il metacarattere ? fa sì che il carattere precedente corrisponda zero o una
volta (al più).

Così /c?ola/ trova cola e ola ma non ccola.

/c*ola/ invece trova cola, ola e ccola.
11
Bioinformatica
Ancora quantificatori

PERL consente di trovare il numero esatto di corrispondenze
desiderate usando le parentesi graffe { }:
 pat{n,m}

In questo caso, n è il numero minimo di corrispondenze e m il
numero massimo di corrispondenze, mentre pat è il gruppo di
caratteri da quantificare;

Vediamo alcuni esempi:
 /x{5,10}/ x occorre almeno 5 volte, ma non più di 10
 /x{9,}/
x occorre almeno 9 volte, ma anche di più
 /x{0,4}/
x occorre fino a 4 volte, ma anche 0
 /x{8}/
x occorre esattamente 8 volte
12
Bioinformatica
.*

La scrittura .* consente di trovare qualsiasi cosa tra due cose
desiderate;

Ad es. /first.*last/ cerca di trovare la parola first seguita da
qualsiasi cosa, quindi la parola last:
 first then last;
 The good players get picked first, the bad last;
 The first shall be last, and the last shall be first;
13
Bioinformatica
Classi di caratteri




Un’altra pratica comune nelle espressioni regolari è chiedere una
corrispondenza di “uno qualsiasi di questi caratteri”
Le espressioni regolari di PERL offrono un tale strumento (classe di
caratteri).
Per scrivere una classe di caratteri, i caratteri contenuti devono essere
racchiusi tra parentesi quadre [ ].
I caratteri in una classe di caratteri sono trattati come un carattere singolo
durante la corrispondenza:







14
[abcde]
[a-e]
[Gg]
[0-9]
[0-9]+
[A-Za-z]{5}
[*!@#$%&()]
Corrisponde a qualsiasi a,b,c,d o e
Idem
Corrisponde a G o a g
Una cifra
Una o più cifre in sequenza
Qualsiasi gruppo di cinque caratteri alfab.
Tutti questi caratteri di punteggiatura. In questo
caso * rappresenta un letterale.
Bioinformatica
Classi di caratteri (2)



Se il primo carattere di una classe di caratteri è un accento
circonflesso (^), la classe viene negata:
 /[^A-Z]/
In questo caso trova caratteri alfabetici non maiuscoli.
Poiché ], ^ e – sono speciali in una classe di caratteri, esistono
alcune regole per la corrispondenza di questi caratteri in modo
letterale:
 Per trovare un ^ letterale si deve esser certi che non sia il
primo carattere della classe;
 Per trovare un ] letterale è necessario inserirlo come primo
carattere o farlo precedere da un \: /[abc\]]/.
 Per inserire un – letterale è necessario inserirlo come primo
carattere o farlo precedere da un \.
15
Bioinformatica
Classi speciali di caratteri

\w
\W
\d
\D
\s
\S

Esempi

/\d{5}/
/\s\w+\s/






16
un carattere parola; equivale a [a-zA-Z0-9_]
un carattere non parola (inverso di \w)
una cifra; equivale a [0-9]
un carattere diverso da una cifra
uno spazio bianco; equivale a [ \t\f\r\n]
un carattere che non sia uno spazio bianco
corrisponde a 5 cifre
corrisponde a un gruppo di caratteri parola
circondati da uno spazio bianco
Bioinformatica
Gruppi e alternanze

In un’espressione regolare può capitare di voler sapere se viene
trovato uno qualsiasi di un insieme di pattern. La soluzione si
chiama alternanza:
if (/dogs|cats/) {
print “\$_ contains a pet\n”;
}

Se cerchiamo però le parole frog, bog, log, flog o clog
l’espressione /frog|bog|log|flog|clog/ diventa troppo ripetitiva. In
questo caso:
 /(fr|b|l|fl|cl)og/
17
Bioinformatica
Gruppi e alternanze (2)


E’ possibile nidificare le parentesi per formare gruppi all’interno di altri
gruppi.
 /(fr|b|(f|c)?l)og/
In un contesto elenco l’op. di corrispondenza restituisce una lista delle
porzioni dell’espressione trovata racchiuse in parentesi. Ogni valore in
parentesi è un valore di ritorno della lista oppure 1 se il pattern non
contiene parentesi:
$_=“apple is red”;
($fruit, $color)=/(.*)\sis\s(.*)/;


In questo caso il pattern trova qualsiasi cosa (come gruppo), quindi lo
spazio bianco, la parola is, un altro spazio bianco e ancora qualsiasi cosa
(sempre come gruppo).
Le due espressioni raggruppate sono restituite all’elenco sul lato sinistro e
assegnate a $fruit e $color.
18
Bioinformatica
Riferimenti




I riferimenti si usano per indicare al motore di espressioni regolari dove
cercare il pattern: all’inizio della stringa o alla fine.
Il carattere ^ all’inizio di un’espressione regolare fa sì che l’espressione
corrisponda solo all’inizio di una riga.
 /^video/ trova la parola video solo se si trova all’inizio di una riga
Il simbolo $ alla fine di un’espressione regolare fa sì che il pattern
corrisponda solo alla fine di una riga.
 /earth$/ trova earth ma solo alla fine di una riga.
Altri esempi
 /^Help/
Le righe che iniziano con Help
 /^Frankly.*darn$/
Le righe che iniziano con Frankly e finiscono con
darn e tutto ciò che sta in mezzo
 /^hysteria$/
Le righe che contengono solo la parola hysteria
 /^$/
Righe vuote
 /^/
Tutte le righe
19
Bioinformatica
Sostituzione

Per sostituire i pattern trovati:
s/patterncercato/sostituzione/;


L’op. di sostituzione s/// (dove / può essere sostituito con altri caratteri, es.
s###) cerca $_ per patterncercato e sostituisce l’intera espressione
regolare trovata con sostituzione.
L’operatore restituisce il numero di corrispondenze o sostituzioni eseguite,
o 0 se non ha trovato nulla:
$_=“Our house is in the middle of our street”;
s/middle/end/;
s/in/at/;
if (s/apartment/condo/) {
# questo codice non è raggiunto
}
20
Bioinformatica
Lavorare con altre variabili

Piuttosto che lavorare con $_ sarebbe meglio in generale
lavorare con altre variabili;

Per usare l’operatore di corrispondenza e l’operatore di
sostituzione su variabili diverse da $_ è necessario associarle alla
variabile usando l’op. di associazione =~:
$weight=“185 lbs”;
$weight=~s/ lbs//; # toglie lbs dalla stringa

L’op. =~ non effettua assegnazioni ma si limita a prendere l’op. di
destra e a farlo agire sulla variabile a sinistra.
21
Bioinformatica
Modificatori e corrispondenze multiple

Per trovare parole senza preoccuparsi se sono maiuscole o minuscole:
/[Mm][Aa][Cc][Bb][Ee][Tt][Hh]/;

Ovviamente PERL offre una soluzione più comoda:
/macbeth/i;

Un altro modificatore per le corrispondenze e le sostituzioni è il
modificatore di corrispondenza globale g: l’espressione regolare (o
sostituzione) è eseguita ripetutamente nell’intera stringa, effettuando ogni
corrispondenza (o sostituzione) subito dopo la prima;

I modificatori possono essere combinati specificandoli tutti dopo
l’operazione di corrispondenza o sostituzione. Per es. gi trova tutte le
occorrenze di pattern nella stringa, in maiuscolo o minuscolo.
22
Bioinformatica
Modificatori

In un contesto elenco, il modificatore di corrispondenza globale restituisce
una lista di tutte le porzioni dell’espressione regolare racchiuse tra
parentesi:
$_=“One fish, two frog, red fred, blue foul”;
@F=m/\W(f\w\w\w)/g; # restituisce in @F fish frog fred foul

In un contesto scalare il modificatore g itera la corrispondenza sulla stringa
restituendo vero per ogni corrispondenza e falso quando non trova più
corrispondenze:
$letters=0;
$phrase=“What’s my line?”;
while($phrase=~/\w/g) {
$letters++;
}
23
Bioinformatica
Riferimenti all’indietro

Quando si usano le parentesi nelle espressioni regolari, PERL
memorizza la porzione della stringa obiettivo che corrisponde a
ogni espressione in parentesi;

Queste porzioni trovate sono salvate in una variabile speciale di
nome $1 (per il primo insieme di parentesi), $2 (per il secondo)
etc;

Il pattern dell’esempio seguente trova i numeri telefonici del
Nord America – per. Es. 800-555-1212 – e memorizza ogni
porzione in $1, $2 e $3:
if (/(\d{3})-(\d{3})-(\d{4})/) {
print “The area code is $1”;
}
24
Bioinformatica
La funzione grep

PERL offre una funzione particolare per cercare pattern negli array:
grep espressione, lista
grep blocco lista

La funzione grep itera ogni elemento nella lista ed esegue l’espressione o
blocco. Nell’espressione o blocco, $_ è impostata a ogni elemento della
lista valutato. Se l’espressione restituisce vero, l’elemento è restituito da
grep:
@dogs=qw(greyhound bloodhound terrier mutt chihuahua);
@hounds=grep /hound/, @dogs;

In questo caso ogni elemento di @dogs è assegnato, a turno, a $_.
L’espressione /hound/ è quindi testata su $_. Ogni elemento che restituisce
vero, viene inserito in una lista restituita da grep e memorizzata in
@hounds.
25
Bioinformatica
Ancora grep

E’ importante notare che $_ nell’espressione si riferisce al valore
effettivo nella lista, non a una copia. Modificare $_ cambia
l’elemento originale nell’elenco:
@hounds=grep s/hound/hounds/, @dogs

Ora @hounds contiene greyhounds e bloodhounds, con una s
alla fine. L’array @dogs originale è anch’esso modificato;

grep può essere usato con qualsiasi altra funzione:
@longdogs=grep length($_)>8, @dogs;
26
Bioinformatica
La funzione map

map ha una sintassi identica a grep ma restituisce il valore
dell’espressione (o blocco), non il valore di $_. Si può usare la
funzione map per produrre un secondo array basato sul primo:
@words = map { split ‘ ‘, $_ } @input;

In questo caso ogni elemento dell’array @input è diviso sugli
spazi, producendo una lista di parole, che viene aggiunta alla lista
restituita dalla funzione map. Una volta divisa ogni riga consecutiva
di @input, le parole accumulate sono memorizzate in @words.
27
Bioinformatica
Gli hash

Gli hash rappresentano un altro tipo di dati collettivo;

Come gli array, gli hash contengono una serie di scalari. La differenza tra
array e hash consiste nel fatto che gli hash accedono ai dati scalari per
nome, invece di usare un valore numerico come fanno gli array;

Gli elementi degli hash sono composti da due parti: una chiave e un valore.
La chiave identifica ogni elemento dell’hash, mentre il valore rappresenta i
dati associati alla chiave. Questa relazione è definita come coppia chiavevalore;

Esempi di strutture dati con natura hash sono i numeri seriali dei prodotti,
la registrazione di pazienti le bollette, il file system del disco, raccolte CD,
etc.
28
Bioinformatica
Gli hash in PERL

Un hash in PERL può contenere tutti gli elementi desiderati o almeno quelli
consentiti dalla memoria disponibile nel sistema;

Gli hash vengono ridimensionati man mano che si aggiungono e si
eliminano elementi;

L’accesso ai singoli elementi è molto rapido e non rallenta in modo
significativo man mano che l’hash aumenta di dimensioni;

Le chiavi dell’hash possono avere la lunghezza desiderata (sono scalari) così
come le parti dei dati;

Le variabili hash sono indicate dal segno percentuale %. Non condividono i
nomi con gli array e gli scalari. Ad es. possiamo avere un hash di nome %a,
un array di nome @a e uno scalare di nome $a.
29
Bioinformatica
Riempire l’hash

E’ possibile creare singoli elementi di hash come segue:
$Authors{‘Dune’}=‘Frank Herbert’;

In questo es. viene assegnato un elemento all’hash %Authors. La chiave di
questo elemento è il termine ‘Dune’, mentre i dati sono costituiti dal nome
‘Frank Herbert’;

Il valore associato alla chiave, $Authors{‘Dune’}, può essere considerato
come qualsiasi altro scalare;

Perché abbiamo usato $Authors anziché %Authors? Come gli array quando
gli hash sono rappresentati come singola entità, presentano un indicatore
davanti al nome della variabile (%). Quando si accede ad un singolo
elemento invece si accede ad uno scalare.
30
Bioinformatica
Inserimento di valori nell’hash
$food{‘apple’}=‘fruit’;
$food{‘pear’}=‘fruit’;
$food{‘carrot’}=‘vegetable’;

Questa operazione si può abbreviare così:
%food = (‘apple’, ‘fruit’, ‘pear’, ‘fruit’, ‘carrot’, ‘vegetable’);
31
Bioinformatica
Operatore virgola-freccia =>

Questo operatore consente di rendere le assegnazioni più
leggibili:
%food = (‘apple’ => ‘fruit’, ‘pear’ => ‘fruit’, ‘carrot’ =>
‘vegetable’);

E’ possibile scrivere i termini sinistri degli operatori => senza
apici. Inoltre una chiave hash a parola singola tra parentesi graffe
viene automaticamente racchiusa tra apici:
$Books{Dune} = ‘Frank Herbert’;
%food = (apple => ‘fruit’, pear => ‘fruit’, carrot =>
‘vegetable’);
32
Bioinformatica
Ottenere i dati da un hash
%Movies = (‘The Shining’ => ‘Kubrick’, ‘Ten Commandments’
=> ‘DeMille’, Goonies => ‘Donner’);
print $Movies{‘The Shining’};

Spesso non è conveniente accedere a ogni chiave per nome. La
funzione keys può essere usata per recuperare tutte le chiavi di
un hash restituite come elenco, che può essere quindi esaminato
per trovare tutti gli elementi dell’hash:
foreach $film (keys %Movies) {
print “$film was directed by $Movies($film).\n”;
}
33
Bioinformatica
Recuperare valori

La funzione values consente di recuperare tutti i valori
memorizzati in un hash:
@Directors=values %Movies;
@Films=keys %Movies;

Ogni elemento di @Directors e @Films contiene un riferimento
alla stessa coppia chiave-valore di %Movies. Il nome del regista
contenuto in $Directors[0] corrisponde al nome del film
memorizzato in $Films[0] e così via.
34
Bioinformatica
Invertire l’hash

A volte è necessario recuperare elementi individuali dall’hash in
base al valore invece che in base alla chiave. Il metodo migliore
per far questo è invertire l’hash, cioè creare un nuovo hash in cui
tutte le chiavi dell’hash originale diventano valori e i valori
diventano chiavi:
%Movies = (‘The Shining’ => ‘Kubrick’, ‘Ten Commandments’
=> ‘DeMille’, Goonies => ‘Donner’);
%ByDirector= reverse %Movies

Se i valori (che devono diventare chiavi) non sono univoci si finirà
per avere un hash con meno elementi di quello originale. Quando
i valori duplicati vengono inseriti nel nuovo hash, le chiavi presenti
sono sostituite con quelle nuove.
35
Bioinformatica
Liste e hash

Quando un hash viene usato in un contesto elenco, PERL lo
trasforma in una lista normale di chiavi e valori. Questa può
essere assegnata agli array:
%Movies = (‘The Shining’ => ‘Kubrick’, ‘Ten Commandments’
=> ‘DeMille’, Goonies => ‘Donner’);
@Data = %Movies;

E’ possibile eseguire qualsiasi operazione di array normale su
@Data e riassegnare l’array a %Movies:
%Movies = @Data
36
Bioinformatica
Ancora sugli hash

Per copiare un hash è possibile assegnarlo semplicemente ad un
altro hash:
%New_Hash = %Old_Hash;

E’ possibile inserire hash all’interno di hash:
%Both = (%First, %Second);
%Additional = (%Both, key1 => ‘value1’, key2 => ‘value2’);

Se %Second contiene una chiave che compare anche in %First, la
seconda occorrenza della coppia chiave-valore sostituisce la
prima in %Both.
37
Bioinformatica
Controllo delle chiavi in un hash

Per verificare se una chiave esiste in un hash:
if( exists $Hash{keyval} ) {
…
}
38
Bioinformatica
Rimuovere chiavi da un hash

Nel modo seguente:
delete $Hash{keyval};

Per rimuovere tutte le chiavi e i valori:
%Hash = ();
39
Bioinformatica
Impiego dell’hash: determinare le
distribuzioni di frequenze
while ( <>) {
while ( /(\w[\w-]*)/g ) {
$Words{$1}++;
}
}

Il pattern cercato è un carattere parola \w seguito da nessuno o più caratteri parola
oppure trattini [\w-]*;

Con le parentesi la stringa corrispondente viene memorizzata in $1;

$1 viene impostato, a turno, a ogni parola corrispondente al pattern della seconda
riga. Questa parola viene usata come chiave all’hash %Words;

La prima volta che appare la parola, la chiave non esiste ancora nell’hash quindi
PERL restituisce un valore undef per la coppia.
40
Bioinformatica
Impiego dell’hash: determinare le
distribuzioni di frequenze (2)

Incrementandolo, PERL imposta il valore a 1, creando la coppia;

La seconda volta che compare una parola, la chiave esiste già
nell’hash %Words e viene incrementata da 1 a 2;

Alla fine l’hash %Words contiene una distribuzione di frequenze
delle parole lette:
foreach ( keys %Words ) {
print “$_ $Words{$_}\n”;
}
41
Bioinformatica
Trovare elementi unici negli array

Consideriamo la seguente lista:
@fishwords=(‘one’, ‘fish’, ‘two’, ‘fish’, ‘red’, ‘fish’, ‘blue’, ‘fish’);

Per trovare gli elementi senza i duplicati:
%seen = ();
foreach (@fishwords) {
$seen{$_}=1; # $_ potrebbe essere sostituito da $fishwords[$i];
}
@uniquewords = keys %seen;
42
Bioinformatica
Elaborare l’intersezione degli array

L’intersezione fra due array:
@stars=(‘R. Reagan’, ‘C. Eastwood’, ‘M. Jackson’, ‘Cher’, ‘S.
Bono’);
@pols=(‘N. Gingrich’, ‘S. Thurmond’, ‘R. Reagan’, ‘S. Bono’, ‘C.
Eastwood’, ‘M. Tatcher’);
%seen=();
foreach (@stars) {
$seen{$_}=1; }
@intersection=grep($seen{$_}, @pols);

La funzione grep viene iterata per l’elenco dei politici impostando
$_ a ogni politico. Il nome viene quindi cercato nell’hash %seen.
Se viene restituito vero il nome è nell’hash e grep restituisce il
valore di $_.
43
Bioinformatica
Elaborare la differenza tra due array

La differenza tra due array:
@stars=(‘R. Reagan’, ‘C. Eastwood’, ‘M. Jackson’, ‘Cher’, ‘S.
Bono’);
@pols=(‘N. Gingrich’, ‘S. Thurmond’, ‘R. Reagan’, ‘S. Bono’, ‘C.
Eastwood’, ‘M. Tatcher’);
%seen=();
foreach (@stars) {
$seen{$_}=1; }
@difference=grep(! $seen{$_}, @pols);

Per i nomi di @pols che compaiono in %seen, grep restituisce
falso e tali nomi non vengono inseriti in difference.
44
Bioinformatica
Ordinare gli hash
foreach ( sort keys %Words ) {
print “$_ $Words{$_}\n”;
}

E’ possibile ordinare secondo quanto specificato in un blocco:
foreach ( sort { $Words{$a} <=> $Words{$b} } keys %Words ) {
print “$_ $Words{$_}\n”;
}

Il blocco fornito per ordinare viene chiamato ripetutamente con $a e $b
impostati a ogni coppia di valori che sort richiede al codice di ordinare. In
questo caso $a e $b sono impostati alle varie chiavi di %Words. Invece di
confrontare $a e $b direttamente, il codice cerca i valori di tali chiavi e li
confronta.
45
Bioinformatica
Funzioni

Per creare subroutine definite dall’utente:
sub subroutine_name {
…
}

Ad es.
Sub countdown {
for ($i=10; $i>=0; $i-) {
print “$i –”;
}
}
46
Bioinformatica
Richiamare subroutine

Quando il programma deve usare il codice della subroutine:
&countdown();

Oppure:
countdown();

La seconda sintassi può essere usata se la subroutine è già stata
dichiarata nel codice;

Quando viene chiamata la subroutine, PERL ricorda la sua
posizione, esegue il codice della subroutine e ritorna alla
posizione memorizzata.
47
Bioinformatica
Chiamare subroutine da altre subroutine
sub world {
print “World!”;
}
sub hello {
print “Hello, “;
world();
}
hello();
48
Bioinformatica
Restituire valori dalle subroutine

Una subroutine ha un valore detto valore di ritorno;

Questo è il valore dell’ultima espressione valutata nella
subroutine o un valore restituito esplicitamente dall’istruzione
return:
sub two_by_four {
2 * 4;
}
print 8*two_by_four();
49
Bioinformatica
Return

Restituire un valore:
sub x_greaterthan100 {
return(1) if ( $x > 100 );
0;
}
$x = 70;
if (x_greaterthan100()) {
print “$x is greater than 100\n”;
}
50
Bioinformatica
Restituire valori complessi

Le subroutine possono restituire scalari, array e hash:
sub shift_to_uppercase {
@words = qw( cia fbi un nato unicef );
foreach (@words) {
$_ = uc($_);
}
return (@words);
}
@acronyms=shift_to_uppercase();
51
Bioinformatica
Argomenti

Per passare argomenti ad una subroutine si può usare una delle
sintassi seguenti:
subname(arg1, arg2, arg3);
subname arg1, arg2, arg3;
&subname(arg1, arg2, arg3);

La seconda sintassi può essere usata solo se PERL ha già
incontrato la definizione della subroutine.
52
Bioinformatica
Accedere agli argomenti

In una subroutine gli argomenti passati sono accessibili tramite la
variabile speciale @_:
sub printargs {
print join(‘,’, @_);
}
printargs (‘market’, ‘home’, ‘roast beef’);

Per accedere ai singoli argomenti:
sub print_third_argument {
print $_[2];
}
53
Bioinformatica
Ancora sugli argomenti

Le funzioni che prendono più argomenti spesso iniziano
assegnando un nome a questi argomenti, per rendere più chiara
la loro funzione:
sub display_box_score {
($num_hits, $num_at_bats)=@_;
print “For $num_at_bats trips to the plate, “;
print “he’s hitting “, $num_hits/$num_at_bats, “\n”;
}
display_box_score(50, 210);

Modificando @_, o un suo elemento, vengono modificate le
variabili originali nell’elenco di argomenti.
54
Bioinformatica
Passare array e hash
sub sort_numerically {
print “Sorting…”;
return( sort { $a <=> $b } @_); }
@sorted_items=sort_numerically(@items);
Passare due o più array o hash può dare risultati indesiderati:
@first = (1,2,3); @second= (6,5,4);
sub display_arrays {
(@a, @b) = @_;
print “The first array: @a\n”;
print “The Second array: @b\n”; }
display_arrays(@first,@second); #i dati vengono posti tutti in @a e @b è vuoto
55
Bioinformatica
Passare array e hash (2)

I due array @first e @second sono elencati assieme e gli elementi sono
inseriti in @_ durante la chiamata alla subroutine. La fine degli elementi di
@first non è distinguibile dall’inizio degli elementi di @second in @_: si
tratta di un’unica lista molto lunga;

All’interno della subroutine tutti gli elementi vengono assegnati a @a e @b
rimane vuoto;

Insieme a un array o un hash è possibile passare uno o più scalari, ammesso
che questi siano passati prima nella lista di argomenti e si sappia quanti ce
ne sono:
sub lots_of_args {
($first, $second, $third, %hash) = @_;
… }
lots_of_args($foo, $bar, $baz, %myhash);
56
Bioinformatica
Ambito di validità e funzioni pure

Le funzioni pure sono quelle subroutine capaci di funzionare
autonomamente e quindi riutilizzabili da altri programmi:
sub moonweight {
($weight) = @_;
return($weight / 6);
}
print moonweight(150);

Ecco la stessa cosa scritta in modo scadente:
sub moonweight {
return($weight / 6); }
$weight = 150;
print moonweight();
57
Bioinformatica
Ambito di validità e variabili locali

PERL consente di riutilizzare più volte i nomi di variabili con
scopi diversi all’interno di un programma esteso. Le variabili di
PERL sono visibili per impostazione predefinita nel corpo
principale del programma e nelle subroutine (variabili globali);

Per rendere la variabile $weight dell’es. precedente locale
rispetto alla subroutine:
sub moonweight {
my $weight;
($weight) = @_;
return($weight / 6);
}
58
Bioinformatica
Ambito di validità




La parte di programma in cui la variabile è visibile è nota come ambito di
validità della variabile.
Si può usare l’operatore my per dichiarare variabili scalari, array e hash
locali rispetto alla subroutine.
Filehandle, subroutine e variabili speciali di PERL non possono essere
contrassegnati come locali.
Per dichiarare più variabili locali:
my($larry, @curly, %moe);
sub player_stats {
my($num_at_bats, $num_hits, $num_walks)=@_;
…
}
59
Bioinformatica
Altri posti per my

Si possono dichiarare variabili con un ambito di validità ancora più limitato
di quello di una subroutine, ad es. in un blocco:
$y=20;
{
my $y=500;
print “The value of \$y is $y\n”; # Stampa 500
}
print “$y\n”;

# Stampa 20
La dichiarazione può avvenire anche all’interno delle strutture di controllo,
per esempio for, foreach, while o if. E’ anche possibile, da PERL 5.004 in poi,
dichiarare come locali gli iteratori dei cicli for e foreach e le condizioni di
verifica di while ed if:
foreach my $element (@array)
while(my $line=<STDIN>)
60
Bioinformatica
Dichiarare variabili local
sub myfunc {
local($foo)=56;
…
}

$foo è dichiarata come locale rispetto alla subroutine myfunc();

Una variabile dichiarata con local si comporta come una
dichiarata con my;

La differenza consiste nel fatto che una variabile dichiarata con
local può essere vista all’interno del blocco dell’ambito di validità
e all’interno di ogni subroutine chiamata da questo blocco.
61
Bioinformatica
Ricorsività
sub factorial {
my ($num)=@_;
return(1) if ($num <= 1);
return($num * factorial($num – 1));
}
print factorial(6);
62
Bioinformatica
Effettuare ricerche negli scalari: index

Se si vuole semplicemente trovare una stringa all’interno di un altro scalare,
PERL fornisce la funzione index:
index string, substring
index string, substring, start_position


La funzione index inizia a sinistra di string e cerca substring; restituisce la
posizione in corrispondenza della quale viene trovata substring, con 0 che
corrisponde al carattere più a sinistra. Se la substring non viene trovata
restituisce -1.
Opzionalmente si può dare a index una posizione di partenza nella stringa
per l’inizio della ricerca:
index “Ring around the rosy”, “around”; # restituisce 5
@a=qw(oats peas beans);
index join(“ “,@a), “peas”; # restituisce 5
index “dasher dancer prancer vixen”, “da”, 1; # restituisce 7
63
Bioinformatica
Cercare all’indietro con rindex

La funzione rindex opera come index, tranne per il fatto che la
ricerca inizia a destra e procede verso sinistra:
rindex string, substring
rindex string, substring, start_position

Qualche esempio:
$a=“She loves you yeah, yeah, yeah.”;
64
rindex($a, “yeah”);
# restituisce 26
rindex($a, “yeah”, 25);
# restituisce 20
Bioinformatica
Estrarre parti di scalari con substr

La funzione substr fornisce un metodo generico per estrarre
informazioni dagli scalari e per modificarli:
substr string, offset
substr string, offset, length

substr richiede string, che inizia alla posizione offset, e restituisce il
resto della stringa da offset alla fine. Se viene specificato length allora
vengono presi length caratteri:
$a=“I do not like green eggs and ham.”;

print substr($a, 25);
# stampa “and ham.”
print substr($a, 14, 5);
# stampa “green”
Se l’offset specificato è negativo, substr inizia a contare da destra. Ad es.
substr($a, -5) restituisce gli ultimi 5 caratteri di $a. Se length è negativo
substr restituisce dalla posizione iniziale alla fine della stringa, meno
length caratteri.
65
Bioinformatica
Ancora substr

Si può usare substr sul lato sinistro di una espressione di
assegnazione. Quando viene usata a sinistra, substr indica quali
caratteri verranno sostituiti in uno scalare. Il primo valore deve
essere un valore assegnabile:
$a=“countrymen, lend me your wallets”;
# sostituisce il primo carattere di $a con “Romans, C”
substr($a, 0, 1)=“Romans, C”;
# inserisce “Friends ,” all’inizio si $a
substr($a, 0, 0)=“Friends, “;
substr($a, -7, 7)=“ears.”; # sostituisce gli ultimi 7 caratteri
66
Bioinformatica
Traslitterazione
tr/searchlist/replacementlist/


L’operatore di traslitterazione, tr///, cerca in una stringa gli elementi in
searchlist e li sostituisce con gli elementi corrispondenti in replacementlist.
Di default tr/// cerca e modifica la variabile $_. Per cercare e modificare
altre variabili, si usa un operatore di associazione come per le
corrispondenze nelle espressioni regolari:
tr/ABC/XYZ/;
# in $_ sostituisce tutte le A con X, le B con Y, …
$r=~tr/ABC/XYZ/; # la stessa cosa ma con $r

I gruppi logici di caratteri sono accettati con trattini tra di essi; per es. A-Z
rappresenta le maiuscole da A a Z:
tr/A-Z/a-z; # cambia tutte le maiuscole in minuscole
67
Bioinformatica
Traslitterazione (2)

Se replacementlist è vuota o identica a searchlist, i caratteri che
corrispondono vengono contati da tr/// e restituiti. La stringa di
destinazione non viene modificata:
$eyes=$potato=~tr/i//; # conta le i in $potato e mette il risultato in $eyes
$nums=tr/0-9//; # conta le cifre in $_ e mette il risultato in $nums
68
Bioinformatica
Stampa formattata con printf
printf formatstring, list
printf filehandle formatstring, list



La stringa formatstring descrive il formato dell’output, list è una lista di
valori che printf deve visualizzare.
formatstring è una stringa letterale (di solito) o uno scalare. Ogni carattere
in formatstring viene stampato letteralmente, eccettuate quelle sequenze
che iniziano con un %.
Il % indica l’inizio di uno specificatore di campo, il cui formato è:
 %-w.dx
 il segno – e il . decimale sono opzionali. w indica la larghezza totale del
campo, d il numero di cifre decimali, x il tipo di campo. Il segno – indica
la giustificazione a sinistra, altrimenti viene giustificato a destra. Solo %
e x sono obbligatori.
69
Bioinformatica
printf



Alcuni tipi di specificatori:
 c
carattere
 s
stringa
 d
intero decimale, la parte frazionaria viene troncata
 f
numero in virgola mobile
perldoc –f printf
è la pagina del manuale con l’elenco completo dei
tipi di specificatori.
Qualche esempio:
printf(“%20s”,”Jack”); # giustifica a destra “Jack” in 20 car.
printf(“%-20s”,”Jill”); # giustifica a sinistra “Jill” in 20 car.
$amt=7.12;
printf(“%6.2f”,$amt); # stampa “ 7.12”
printf(“%c”, 65); # stampa il carattere ASCII 65, cioè “A”
70
Bioinformatica
Ancora printf

Ogni specificatore di campo usa un elemento della lista. Per ogni
elemento deve esserci uno specificatore di campo e per ogni
specificatore di campo deve esserci un elemento della lista:
printf(“Totals: %6.2f %15s %7.2f %6d”, $a, $b, $c, $d);

La sequenza %% rappresenta un simbolo di percentuale.
71
Bioinformatica
sprintf

La funzione sprintf è identica a printf, tranne per il fatto che
invece di essere stampato, l’output formattato viene restituito da
sprintf, pronto per essere assegnato a uno scalare o per essere
usato in un’altra espressione:
$weight=85;
$moonweight = sprintf(“%.2f”, $weight / 6);
print “You weight $moonweight on the moon”;
72
Bioinformatica
Un elenco come stack



PERL offre la struttura dati stack, implementata solitamente con
array.
Le funzioni per lavorare con gli stack sono:
 push, per collocare elementi in cima allo stack
 pop, per estrarre elementi dalla cima
 shift, per rimuovere elementi dal basso
 unshift, per aggiungere elementi al fondo
Le sintassi sono le seguenti:
pop target_array;
shift target_array;
unshift target_array, new_list;
push target_array, new_list
73
Bioinformatica
Le funzioni dello stack

pop e shift rimuovono un solo elemento da target_array e lo
restituiscono. Restituiscono undef se l’array è vuoto;

Le funzioni push e unshift aggiungono gli elementi di new_list a
target_array:
@band = qw(trombone);
push @band, qw(ukulele clarinet);
$brass=shift @band;
$wind=pop @band;
unshift @band, “harmonica”;
74
Bioinformatica
Lo stack è un array

Gli elementi dell’array in uno stack sono ancora semplicemente
normali elementi di array e possono essere indirizzati con indici;

Il fondo dello stack è l’elemento 0, mentre la sommità è costituita
dall’ultimo elemento;

Usando unshift per aggiungere elementi e pop per eliminarli o
usando push per aggiungere elementi e shift per eliminarli si
realizza una coda.
75
Bioinformatica
La funzione splice
splice array, offset
splice array, offset, length
splice array, offset, length, list


La funzione splice toglie elementi da array a partire da offset e restituisce la
lista degli elementi estratti dall’array.
Valori negativi di offset fanno sì che il conteggio degli elementi inizi alla fine
dell’array. Se viene specificato length, vengono eliminati sono length
elementi. Se viene specificato list, allora vengono eliminati length elementi e
sostituiti con gli elementi di list:
@veg=qw(carrots corn);
76
splice(@veg, 0, 1);
# @veg = corn
splice(@veg, 0, 0, qw(peas));
# @veg = peas, corn
Bioinformatica
La funzione system()

Il modo più semplice per eseguire un comando fuori da PERL, consiste
nell’usare la funzione system, che mette il programma PERL in pausa,
esegue il comando esterno e fa proseguire l’esecuzione del programma
PERL:
system command;

dove command è il comando che si vuole eseguire. Il valore restituito da
system è 0 se tutto va bene e un valore diverso da 0 se si verifica un
problema.
system(“dir /w”); # stampa un elenco di file
if (system(“perldoc –f system”)) {
print “Your documentation isn’t installed correctly!\n”;
}
$file=“myfile.txt”; system(“notepad.exe $file”);
77
Bioinformatica
Catturare l’output

La funzione system non offre un buon sistema per catturare l’output del
comando e fornirlo a PERL per l’analisi. Si può aggirare il problema come
segue:
system(“dir > outfile”);
open(OF,”outfile”) || die “Cannot open output: $!”;
@data=<OF>;
close<OF>;

PERL dispone di un altro metodo per gestire questa situazione: i backtick o
apici rovesciati. Qualsiasi comando all’interno dei backtick `` (ASCII Alt+96)
viene eseguito da PERL come un comando esterno e l’output viene
catturato e restituito come valore di ritorno dei backtick:
$directory=`dir`;
78
Bioinformatica
backtick

Un esempio:
@dir=`dir`;
foreach(@dir) {
…
}

PERL dispone di un altro sistema per rappresentare i backtick: qx{ }:

Al posto di { } si possono usare altre coppie di caratteri come <>,( ), [ ].
$perldoc=qx{perldoc perl};
79
Bioinformatica
Evitare la shell

Consideriamo il seguente esempio:
$myhome = `ls $HOME`;

$HOME è la variabile $HOME di PERL o la variabile $HOME di ambiente
della shell?

$HOME è interpolata da PERL, quindi rappresenta una variabile del
programma;

Per ovviare a questo problema si può inserire un backslash prima delle
variabili che non si vuole vengano interpolate da PERL:
$myhome=`ls \$HOME`;
80
Bioinformatica
Riferimenti

Creiamo e assegniamo una variabile scalare:
$a=“Stones”;




Adesso in memoria esiste un’area etichettata $a che contiene la stringa
“Stones”.
Se si volesse assegnare lo scalare $a a $b, cioè $b=$a, si otterrebbero due
copie dei dati con due nomi diversi.
Ma se si vuole che $b faccia riferimento a $a? Si deve creare un
riferimento.
Per creare un riferimento a una variabile si deve mettere un backslash
prima del nome della variabile con il suo identificatore di tipo:
$ref=\$a;
81
# crea un riferimento a $a
Bioinformatica
Riferimenti (2)

Per ottenere il valore interno a $a tramite $ref occorre
deferenziare $ref:
$ref=\$a; # crea un riferimento a $a
print $$ref; # stampa Stones
$$ref=“Sticks”;
Print $a; # stampa Stick

Ovviamente si può assegnare un riferimento come si farebbe con
qualsiasi altro valore scalare:
$name=”Gandalf”;
$nref=\$name;
$oref=$nref;
82
Bioinformatica
Riferimenti (3)

Si può anche memorizzare un riferimento a un riferimento, come
segue:
$book=“Lord of the Rings”;
83
$bref=\$book;
# riferimento a $book
$bref2=\$bref;
# riferimento a $bref
print $$bref;
# Stampa Lord of the Rings
print $$$bref2;
# Stampa Lord of the Rings
Bioinformatica
Riferimenti ad array

Si possono anche creare riferimenti ad array ed hash. Tali riferimenti vengono creati
nello stesso modo in cui viene creato un riferimento ad uno scalare:
$aref=\@arr;
$$aref[0];
# il primo elemento di @arr
@$aref[2,3];
# una porzione di @arr
@$aref;
# l’intero array @arr

Per maggiore chiarezza:

$$aref[0]
è uguale a ${$aref}[0]

@$aref[2,3]
è uguale a @{$aref}[2,3]

@$aref
è uguale a @{$aref}
foreach $element (@{$aref}) {
print $element; }
84
Bioinformatica
Riferimenti a hash

Per creare un riferimento a hash:
$href=\%hash;
$$href{key};
# una singola chiave in %hash
${$href}{key};
# idem
%$href;
# l’intero hash
foreach $key (keys %$href) {
print $$href{$key};
}
85
Bioinformatica
Riferimenti come argomenti

Ricordiamo che il codice seguente non funziona:
sub getarrays {
my(@a, @b)=@_;
…}

Ma con i riferimenti…
sub getarrays {
my($fruit_ref, $veg_ref)=@_;
print @$fruit_ref;
# Stampa correttamente l’array
print @$veg_ref;
# Stampa correttamente l’array
}
@fruit=qw(apples oranges banana);
@veggies=qw(carrot cabbage turnip);
getarrays(\@fruit, \@veggies);
86
Bioinformatica
Riferimenti e modifiche

Quando i riferimenti a scalari, array o hash vengono passati a
funzioni come argomenti, la funzione può manipolare i dati
originali a cui il riferimento punta:
sub changehash {
my(%local_hash)=@_;
sub changehash {
my($href)=@_;
$local_hash{mammal}=‘bear’;
$$href{mammal}=‘bear’;
return;
return;
}
%hash=(fish => ‘shark’,bird => ‘robin’);
}
changehash(%hash);
%hash=(fish => ‘shark’, bird => ‘robin’);
changehash(\%hash);
87
Bioinformatica
Memorizzazione anonima

Consideriamo il seguente codice:
my $href;
{
my %hash=(phone=>’Bell’, light=>’Edison’);
$href=\%hash;
}
print $$href{light};

Nonostante l’hash sia interno al blocco, esso continuerà ad esistere fuori
dal blocco proprio a causa del riferimento;

PERL offre la possibilità di creare un riferimento senza usare un hash
intermedio: memorizzazione anonima!
88
Bioinformatica
Memorizzazione anonima (2)

Memorizzazione anonima (Creazione di un hash mediante
riferimento):
$ahref={ phone => ‘Bell’, light=> ‘Edison’ };
foreach $key ( keys( %${ahref} ) ) {
print "\n [ $key ] tramite riferimento
= " . ${$ahref}{$key};
print "\n [ $key ] tramite riferimento smart = " . $href->{$key}
}

Un array anonimo:
$aaref=[ qw( Crosby Stills Nash Young ) ];

Ma se un riferimento punta ad una variabile privata, cioè interna
ad un blocco, i dati a cui punta svaniscono quando la variabile
esce dall’ambito di validità.
89
Bioinformatica
Strutture: Liste di liste

Le liste di liste sono spesso utilizzare per rappresentare matrici:
@list_of_lists=(
[ qw(Mustang Bronco Ranger) ],
[ qw(Cavalier Suburban Buick) ],
[ qw(LeBaron Ram) ],
);

$list_of_lists[0][1];
# Bronco, 1a riga, 2° elemento
$list_of_lists[1][2];
# Buick
Per trovare il numero di elementi nella lista esterna:
$#list_of_lists;
#2
scalar(@list_of_lists);
90
#3
Bioinformatica
Liste di liste (2)

Trovare il numero di elementi in uno degli elenchi più interni è
più difficile:
scalar(@{$list_of_lists[2]}); # num di elementi nella riga 3
$#{$list_of_lists[1]}; # indice dell’ultimo elemento della riga 2

Per attraversare ogni elemento nell’elenco degli elenchi:
foreach my $outer (@list_of_lists) {
foreach my $inner (@{$outer}) {
print “$inner ”;
}
print “\n”; }
push(@list_of_lists, [qw(Mercedes BMW Lexus)]); #nuova riga
push(@{$list_of_lists[0]},qw(Taurus)); # nuovo elemento
91
Bioinformatica
I moduli

PERL può essere esteso attraverso l’uso di moduli, collezioni di
routine che permettono di aggiungere funzionalità al linguaggio;

La direttiva use permette di usare un modulo nel proprio
programma PERL. Ad es. per includere il modulo cwd:
use Cwd;

La posizione di tale direttiva nel codice non è importante, anche
se, è meglio inserirla all’inizio del programma;

La funzione cwd, messa a disposizione nel modulo Cwd
restituisce il nome della directory di lavoro corrente.
92
Bioinformatica
Alcuni moduli di PERL: File::Find
use File::Find;
find subref, dirlist;

find ha due parametri: subref è un riferimento a subroutine (si crea con il
nome della subroutine preceduto da backslash; si deve usare la & prima del
nome della subroutine per definire un riferimento ad essa). La subroutine in
questione viene chiamata per ogni file e directory trovato in dirlist.

Troviamo ad es. il file important.doc:
use File::Find;
sub wanted {
if($_ eq “important.doc”) {
print $File::Find::name;
}}
find \&wanted, ‘/documents’;
93
Bioinformatica
Alcuni moduli di PERL: File::Copy

Il modulo File::Copy fornisce il modo per copiare file:
use File::Copy;
copy(“sourcefile”, “destination”) || warn “Could not copy files: $!”;

La funzione copy restituisce 1 in caso di successo oppure 0 se si
è verificato un problema;

Il modulo File::Copy fornisce anche una funzione move che
sposta un file da una directory ad un’altra:
move(“important.doc”, “d:/archives/documents/important.doc”);
94
Bioinformatica
Alcuni moduli di PERL: Net::Ping

Il modulo Net::Ping fornisce il modo di determinare se il sistema
può comunicare in rete (il secondo parametro indica il timeout):
use Net::Ping;
if (pingecho(www.yahoo.com, 15)) {
print “Yahoo is on the network.”;
} else {
print “Yahoo is unreachable.”;
}
95
Bioinformatica
Persistenza dei dati: File DBM

Uno dei modi più semplici per PERL di ricordare i dati in modo organizzato
è mediante i file DBM;

Un file DBM è un file che è stato connesso a un hash di PERL;

Per vincolare il proprio hash a un file DBM:
dbmopen(hash, filename, mode);

Il filename che si fornisce, crea uno o due file su disco rigido con nomi che
sono varianti di filename: filename.pag e filename.dir, oppure filename.db.
PERL usa questi file per memorizzare l’hash;

mode rappresenta le autorizzazioni sui due file DBM che PERL crea;

La funzione dbmopen restituisce vero se l’hash è stato correlato con
successo al file DBM.
96
Bioinformatica
File DBM (2)

Una volta correlato un hash ad un file
dbmopen(%hash, “dbmfile”, 0644) || die “$!”;

si può lavorare tranquillamente con l’hash come visto finora:
$hash{feline}=“cat”;
$hash{canine}=“dog”;

Quando si recuperano le informazioni, PERL riprende chiave e dati dal file
DBM:
print $hash{canine};

Per disconnettere l’hash dal file DBM:
dbmclose(%hash);
97
Bioinformatica
DBM (3)

E’ importante sapere che:
 La lunghezza delle chiavi e dei dati adesso è limitata. Gli hash
associati a un file DBM hanno una lunghezza limitata di chiave e
valore, normalmente intorno ai 1024 caratteri per la
combinazione chiave-valore. Il numero totale di chiavi e valori
invece è limitato solo dal file system;

I valori nell’hash prima di dbmopen vengono persi;

I valori nell’hash mentre quest’ultimo è associato al file DBM
scompaiono dopo l’esecuzione di dbmclose.
98
Bioinformatica
Esaminare gli hash legati a DBM

Consideriamo il codice seguente:
dbmopen(%recs, “records”, 0644) || die “$!”;
foreach my $key (keys %recs) {
print “ $key = $recs{$key}\n”;
}
dbmclose(%recs);

Il codice è corretto ma se l’elenco di chiavi in %recs è ampio l’istruzione
keys %recs potrebbe richiedere del tempo per l’esecuzione. PERL ha
un’altra funzione che permette di iterare su un hash una chiave alla volta:
while( ($key, $value)=each %recs) {
print “ $key = $value\n”;}
99
Bioinformatica
Ancora sui Moduli








EData::Dumper
Per il debugging
CGI & CGI::Pretty
Interfaccia per l’ambiente CGI
DBI
Interfaccia per DB relazionali
DateTime
Date e tempo
HTML::TreeBuilder
HTML parsing
Spreadsheet::ParseExcel Leggere in file Excel
Spreadsheet::WriteExcel creare documenti excel
XML::Twig
trattare dati XML
100
Bioinformatica
Programmazione Orientata agli Oggetti

Una classe è semplicemente un package:
#!/usr/local/bin/perl
package Cat;
sub new {
…
}
sub meow {
…
}

Per inizializzare un oggetto:
$new_object = new ClassName;

Usare un metodo:
$cat->meow();
101
Bioinformatica
Programmazione Orientata agli Oggetti

Esempio:
1: #!/usr/bin/perl
2:
3: package Lampadina;
4: sub new {
5: my $self = shift() || { stato => 'spenta‘, potenza => '0W', attacco => 'baionetta', luce => 'gialla', };
6: bless $self; # Indica a Perl che $self non è una variabile qualsiasi ma un riferimento all’oggetto
7: return $self;
8: }
9:
10: sub switch {
11: my $self = shift; # Reference all’oggetto di cui fa parte
12: $self{state} = $self{state} eq 'accesa' ? 'spenta' : 'accesa';
13: }
14:
15: sub state {
16: my $self = shift; # Reference all’oggetto di cui fa parte
17: return $self{state};
18: }

Shift() prende i parametri di input e li assegna alle variabili
102
Bioinformatica
Programmazione Orientata agli Oggetti

Usare la classe:
1: #!/usr/bin/perl
2: package main;
3:
4: my $lampadina = new Lampadina({stato=>'spenta‘,potenza=>'60W‘
,attacco=>'edison',luce =>'bianca‘,});
5:
6: if ( $lampadina->state() eq 'spenta' ) {
7: $lampadina->switch();
8: print "la lampadina ora è accesa\n";
9: } else {
10: $lampadina->switch();
11: print "la lampadina è spenta\n";
12: }
103
Bioinformatica