GIMP - Copertina - CDROM-edicola |
Articoli
Cos'è il PERL
Questo è il primo di una serie di articoli che non vogliono essere assolutamente un corso sul Perl, ma solo uno stimolo per far vedere quanto questo linguaggio possa essere utile nella ``vita di tutti i giorni''; per un corso intensivo del linguaggio si rimanda alla bibliografia che verrà via via fornita.
Prima della storia del PERL vediamo di capire cosa significa PERL!!!
P.E.R.L. è l'acronimo di Practical Extraction and Report Language o se si preferisce Pathologically Eclectic Rubbish Lister; non si sa quale delle due definizioni sia la più esatta: entrambe sono state dettate direttamente da Larry Wall, autore, mantenitore, implementatore di questo linguaggio.
Larry Wall creò il PERL quando tentava di produrre alcuni report da una serie di file; trovato che awk non soddisfava completamente le sue richieste decise di risolvere il problema scrivendo un tool general-purpose.
Oggi il PERL è diventato un linguaggio di programmazione disponibile su ogni implementazione di Unix, (ma lo si può trovare anche su sistemi diversi dagli Unix quali NT, OS/2 ecc..) la versione attuale è la 5.004 e lentamente sta crescendo e si sta perfezionando sempre più.
Per sapere cosa si può fare con Perl basta fare un bel man perl e leggere direttamente quanto scrive Wall: "Il Perl è un linguaggio interpretato ottimizzato per la scansione di file di testo arbitrari, l'estrazione di informazioni da questi file di testo e la stampa di report basati su queste informazioni. È anche un buon linguaggio per molti lavori di manutenzione di sistema. Il linguaggio è pesato per essere pratico (facile da usare, efficiente e completo) e non per essere bello (piccolo, elegante, minimale)", chi ha già una minima esperienza di Un*x può pensare che il Perl non faccia altro che fare tutto quello che può fare una semplicissima shell di sistema: questo però sarebbe un primo errore: proviamo infatti a pensare a quante sono le shell normalmente presenti in un sistema Un*x (csh, tcsh, zsh, bash...) e quanti linguaggi di script si dovrebbero imparare, in pratica uno per ogni shell. Con Perl un programma scritto su un sistema, ad esempio Linux, funziona su ogni sistema che faccia girare Perl senza essere minimamente modificato.
Perl è molto più conciso rispetto agli script di shell ed è molto più sicuro. Perl è inoltre il linguaggio di programmazione più usato per lo sviluppo di applicazioni CGI, ma è anche molto utile per la scrittura di applicazioni ftp, news, mail, accesso a database etc...
Proprio per la sua propensione per la scrittura di programmi CGI Perl sta diventando sempre più uno strumento utile al Webmaster.
Sintatticamente il Perl è molto simile al C, anche se naturalmente ci sono delle differenze.
Il Perl è un linguaggio interpretato, non è particolarmente semplice ma è anche dotato di una grande potenza e di una grande logicità. La definizione di linguaggio interpretato è però un po' limitativa: in realtà uno script prima di essere eseguito viene letto nella sua interezza, ne viene controllata la sintassi, viene compilato e quindi eseguito; alla fine dell' esecuzione il "compilato" viene rimosso dalla memoria. Spesso il Perl viene utilizzato per la creazione di prototipi di programmi che poi vengono sviluppati in altri linguaggi di programmazione, ed è estremamente comodo per la scrittura di programmi "usa e getta". Nella versione 5.xxx alla tradizionale programmazione procedurale sono stati aggiunti una più moderna programmazione orientata agli oggetti ed un supporto alla modularità.
Non sono ancora stati creati compilatori Perl, probabilmente perché non se ne sente una reale esigenza.
Un colpo d'occhio e capisci che...
Le variabili non devono essere dichiarate e la conversione fra tipi di variabile diverse avviene in modo automatico: è infatti possibile assegnare, ad esempio, un intero ad una stringa o viceversa senza nemmeno ricevere un ``warning'' dall'interprete-compilatore.
Le variabili che possiamo trovare sono di 3 tipi:
Per dati scalari si intendono:
Le variabili di tipo scalare sono identificati da nomi che iniziano obbligatoriamente con il carattere speciale "$" e possono avere nomi di lunghezza variabile:
$ma_guarda_come_e_lungo_il_nome_di_questa_variabile_perl
Variabili di tipo numerico
Tenendo presente che internamente il Perl considera i numeri come se fossero tutti nello stesso formato, ecco alcune semplici dichiarazioni di variabili numeriche:
Variabili numeriche di tipo floating point
2.25
1.39e55 # 1.39x10^55
1.39E55 # idem come sopra
-4.3e22 # -4.3x10^22Variabili numeriche di tipo intero
199
1436
-22450
2849Possono essere dichiarate variabili di tipo ottale facendo precedere il valore numerico per 0, oppure si possono dichiarare variabili di tipo esadecimale facendo precedere il valore numerico da 0x:
0xff # Dichiara il valore esadecimale FF, corrispondente al valore 255 in decimale
0377 # Dichiara il valore ottale 377, corrispondente al valore 255 in decimaleVariabili di tipo stringa
Non sono altro che normali sequenze di caratteri e possono essere di due tipi, singled-quoted o double-quoted: vediamone qualche esempio:
'ciao' # stringa singled-quoted che corrisponde a 5 caratteri c, i, a, o
'l'apostrofo' # stringa singled-quoted che corrisponde a l,',a,p,o,s,t,r,o,f,o
"Linux the choice of a\nGNU generation" # Linux the choice of a GNU <newline> generation
"Linux" x 5 # corrisponde alla stringa "LinuxLinuxLinuxLinuxLinux"
Tipo di comparazione | Simbolo |
Uguale | eq |
Non uguale | ne |
Minore | lt |
Maggiore | gt |
Minore uguale | le |
Maggiore uguale | ge |
Array di scalari
Nulla in particolare da dire riguardo agli array di scalari,
il cui concetto è simile a quello degli altri linguaggi di programmazione;
il nome di un array deve iniziare con il carattere @ (come in @nome_della_variabile).
Per accedere ad un elemento di un array di scalari basta utilizzare
la sintassi $_nome_del_array[indice]; quindi per accedere al 5 elemento
dell'array @pluto si dovrà utilizzare: $pluto[4], tendendo conto
che il primo elemento di un array ha indice 0.
Array associativi
Meritano una breve spiegazione gli array associativi, nei quali si può accedere ad ogni dato attraverso un indice: è possibile rappresentare, in prima istanza, un array associativo come una tabella nella quale la prima colanna rappresenta le chiavi di accesso ai dati, mentre la seconda colonna rappresenta il dato stesso. Vediamo una tabella e proviamo a vedere come tradurre il tutto in Perl:
1 | GNU/Linux |
2 | BeOS |
3 | Windows NT |
Ecco come tradurre la struttura dati in Perl:
$tabella_so{1}= "GNU/Linux";
$tabella_so{2}= "BeOS";
$tabella_so{3}= "Windows NT";Per accedere all'elemento con chiave 2 (BeOS) è sufficiente scrivere:
print $tabella_so{2} # Scrive il valore BeOSÈ interessante vedere come pur dovendo riferirsi all'intero array associativo con %nome_della_variabile, in questo caso %tabella_so, per riferirsi ad un singolo elemento dell'array si debba usare la sintassi $nome_del_array_associativo{elemento}.
Espressioni regolari in Perl
Proprio perché il Perl è nato per essere un linguaggio che estraesse dati da file e li presentasse in forma diversa, la sua potenza nel trattare file di testo è realmente incredibile: ne sono un esempio le espressioni regolari.
Una expressione regolare è un pattern, un template, che deve corrispondere ad una stringa; il concetto di espressione regolare non è nuovo all'ambiente Un*x, programmi come Emacs, VI o grep usano espressioni regolari: se vogliamo ad esempio trovare nel nostro filesystem un file che contenga le lettere "unx" possiamo usare un comandino del genere:
find | grep unx
Quante volte è capitato di trovarsi davanti ad una domanda alla quale di doveva rispondere con un Y o un N, formulata nel seguente modo:
Would you like to continue?Le risposte plausibili possono essere:
Y
yes
Yes
YES
n
N
n
No
NO
print "Continue?" # Scrive continue a video ma NON va a capo
if (<STDIN> =~ /^[yY]/) # Controlla se la risposta inserita dall'utente nello standard input
# inizia con una y o una Y
{
# gestisce la risposta y
} else
{
# Gestisce la risposta n
}
E il gioco è fatto, prima piccola magia del Perl. ;-)
Un'altra piccola magia: anfinger Una delle macchine che mi trovo
ad amministrare è un server di posta elettronica di studenti di
un università; il nome degli studenti non compare nel loro login
name, e per cercare un utente con il cognome Rossi è necessario
utilizzare il comando finger. Per svariate ragioni il finger è stato
levato dalla macchina, anche per gli utenti che eseguono comandi da shell;
a questo scopo ho creato A nice Finger di cui segue il listato:
invocato con la sintassi indicata anfinger restituisce l'indirizzo di posta
elettronica dello studente che ha il nome dato sulla riga di comando:
Eccone il listato:
1 #!/usr/bin/perl # # ANFinger ############################################################################## # Variabili per le installazioni differenti e per le successive modifiche # ############################################################################## 2 $FILE_PASSWD=" /etc/passwd"; # questa variabile deve essere cambiata secondo le # impostazioni della macchina in cui viene usato # ANFinger 3 $versione = "1.00"; # La versione attuale del programma 4 $notfound = 0 ; # Inizializzo la variabile 5 if ($ARGV[0] eq "") { 6 print "Utilizzare anfinger <nome utente>\n"; 7 exit; } 8 $nome =~ tr/A-Z/a-z/; 9 print "\n\nANFinger $versione by Corrado Ignoti\n"; 10 print "Risultati della ricerca effettuata con la chiave $ARGV[0]\n\n"; 11 open (password, $FILE_PASSWD); # accedo al file passwd 12 while ($name = <password>) { 13 chop ($name); 14 @login = split (/:/, $name); 15 $login[4] =~ tr/A-Z/a-z/; 16 if ($login[4] =~ /$ARGV[0]/i) { 17 print "$login[4], e-mail: $login[0]\@$ENV{HOST}.$ENV{DOMAIN}\n"; } else { $notfound = $notfound + 1; } } 18 close (password); if ($notfound == 1) { 19 die "Non ci sono utenti per la chiave specificata\n\n"; } if ($notfound > 1) { die "\n\nNon ci sono altri utenti per la chiave specificata\n\n"; } |
la riga 1 dice alla shell che il listato seguente deve essere interpretato attraverso il programma perl; nella riga 5 troviamo una cosa interessante: viene controllato se anfinger è stato invocato senza argomenti sulla linea di comando, il funzionamento di ARGV è simile a quello del C ( o meglio di Java), infatti $ARGV[0] (il primo elemento dell'array @ARGV) è il primo argomento passato sulla riga di comando dopo il nome del file.
la riga 8 è un espressione regolare che trasforma il contenuto della variabile $nome da maiuscolo a minuscolo, riassegnandolo alla variabile $nome stessa
la riga 11 accede al file /etc/passwd, mentre il ciclo while
alla riga 12 scandisce sequenzialmente il file, l'istruzione alla
riga 13, cancella l'ultimo carattere di una stringa; la cosa interessante
è però l'istruzione alla riga 14, con la quale si
forma l'array @login che contiene gli elementi di una riga del file passwd:
ogni campo dell'array contiene un elemento diverso del file; per suddividere
gli elementi si utilizza il carattere ``:'', infatti il file passwd è
così strutturato:
nome:password:uid:gid:fullname:home/directory
$login[0] = nome
$login[1] = password
$login[2] = uid
.....
$login[4] = homedirectory
la riga 17 comunica i dati all'utente (si noti l'uso di \@ per
visualizzare il carattere ``@'' e $ENV{HOST}.$ENV{DOMAIN} per la visualizzazione
rispettivamente della variabile contenente il nome dell' host e del dominio).
GIMP - Copertina - CDROM-edicola |