index | project | pods | responsabili |
NOMEperlsyn - La sintassi del Perl
DESCRIZIONEUn programma Perl consiste in una sequenza di dichiarazioni e istruzioni che vengono eseguite dall'inizio alla fine. Cicli, subroutine e altre strutture di controllo vi permettono di saltare all'interno del codice. Perl è un linguaggio free-form [A forma libera, NdT], potete formattarlo e indentarlo come preferite. Lo spazio bianco serve generalmente a separare i simboli, diversamente da altri linguaggi come Python dove è un'importante parte della sintassi. Molti degli elementi sintattici del Perl sono opzionali. Piuttosto che richiedere di mettere le parentesi ad ogni chiamata a funzione e di dichiarare ogni variabile, spesso potete omettere questi elementi espliciti e Perl cercherà di capire cosa intendete. Questo è conosciuto come Do What I Mean [Fa quello che intendo, NdT], abbreviato DWIM. Ciò permette ai programmatori di essere pigri e di scrivere il codice in uno stile a loro confortevole. Il Perl adotta sintassi e concetti da molti linguaggi: awk, sed, C, Bourne Shell, Smalltalk, Lisp e perfino dall'inglese. Altri linguaggi hanno preso in prestito la sintassi da Perl, in particolare le estensioni delle sue espressioni regolari. Cosí se avete già programmato con un altro linguaggio troverete frammenti familiari in Perl. Spesso funzionano allo stesso modo, ma consultate perltrap per informazioni su cosa differiscono.
DichiarazioniLe uniche cose che avete bisogno di dichiarare in Perl sono i formati dei report e
le subroutine (e a volte nemmeno le subroutine). Una variabile contiene il valore
indefinito ( my $a; if ($a) {} sono esenti da avvertimenti (perché sono casi in cui importa la veridicità
piuttosto che la definizione). Operatori come my $a; $a++; sono anch'essi esenti da questi avvertimenti. Una dichiarazione può essere posta ovunque si possa mettere
un'istruzione, ma non ha effetti sulla sequenza primaria delle istruzioni--le dichiarazioni
hanno tutte effetto al momento della compilazione. Tipicamente tutte le dichiarazioni
vengono poste all'inizio o alla fine di uno script. Tuttavia, se state usando una variabile
lessicale privata creata con Dichiarare una subroutine permette di usare il nome di quella subroutine come operatore
di lista da quel punto in poi del programma. Potete dichiarare una subroutine senza
definirla usando sub mionome; $io = mionome $0 or die "impossibile utilizzare mionome"; Va notato che Le dichiarazioni delle subroutine possono anche essere caricate con l'istruzione
Una sequenza di istruzioni può contenere delle dichiarazioni di variabili private, ma a parte questa funzione le dichiarazioni esse agiscono come istruzioni ordinarie, e vengono elaborate con il resto come se fossero istruzioni ordinarie. Questo significa che in realtà hanno degli effetti sia durante la compilazione che durante l'esecuzione.
CommentiIl testo, dal carattere
Istruzioni SempliciL'unico tipo di istruzione semplice è un'espressione valutata per i suoi
effetti secondari. Ogni istruzione semplice deve terminare con un punto e virgola, salvo che
sia l'istruzione finale in un blocco nel quel caso è opzionale. (Un punto
e virgola è tuttavia incoraggiato se il blocco è lungo più di
una riga, così potete eventualmente aggiungere un'altra riga). Da notare che
ci sono operatori come
Verità e FalsitàIl numero 0, le stringhe
Modificatori di IstruzioneQualunque instruzione semplice può eventualmente essere seguita da un SINGOLO modificatore, subito prima del punto e virgola finale (o della fine del blocco). I possibili modificatori solo: if ESPRESSIONE unless ESPRESSIONE while ESPRESSIONE until ESPRESSIONE foreach LISTA L'
print "I basset hound hanno lunghe orecchie" if length $orecchie >= 10; vai_fuori() and gioca() unless $sta_piovendo; Il modificatore print "Ciao $_!\n" foreach qw(mondo Dolly infermiera);
# Ciascuna istruzione conta da 0 a 10. print $i++ while $i <= 10; print $j++ until $j > 10; I modificatori do { $riga = <STDIN>; # ... } until $riga eq ".\n"; Vedete perlfunc/do. Osservate inoltre che le istruzioni di
controllo di ciclo descritte in seguito NON funzioneranno con questo
costrutto, perché i modificatori non accettano etichette di ciclo.
Spiacenti. Potete sempre mettere un altro blocco all'interno (per do {{ next if $x == $y; # qui si fa qualcosa }} until $x++ > $z; Per CICLO: { do { last if $x = $y**2; # qui si fa qualcosa } while $x++ <= $z; } NOTA: Il comportamento di un'istruzione
Istruzioni ComposteIn Perl, una sequenza di istruzioni che definisce uno scope viene chiamata
blocco. A volte un blocco è delimitato dal file che lo contiene (nel caso di
un file richiesto [con In generale, però, un blocco è delimitato da parentesi graffe. Chiameremo questo costrutto sintattico un BLOCCO. Le istruzioni composte che seguono possono essere utilizzate per controllare il flusso del programma: if (ESPRESSIONE) BLOCCO if (ESPRESSIONE) BLOCCO else BLOCCO if (ESPRESSIONE) BLOCCO elsif (ESPRESSIONE) BLOCCO ... else BLOCCO ETICHETTA while (ESPRESSIONE) BLOCCO ETICHETTA while (ESPRESSIONE) BLOCCO continue BLOCCO ETICHETTA until (ESPRESSIONE) BLOCCO ETICHETTA until (ESPRESSIONE) BLOCCO continue BLOCCO ETICHETTA for (ESPRESSIONE; ESPRESSIONE; ESPRESSIONE) BLOCCO ETICHETTA foreach VAR (LIST) BLOCCO ETICHETTA foreach VAR (LIST) BLOCCO continue BLOCCO ETICHETTA BLOCCO continue BLOCCO Osservate che, contrariamente a C e Pascal, queste sono definite in termini di BLOCCHI, non di istruzioni. Ciò significa che le parentesi graffe sono obbligatorie -- non sono ammesse istruzioni pendenti. Se volete scrivere condizioni senza parentesi graffe ci sono parecchi altri modi di farlo. Le seguenti istruzioni fanno tutte la stessa cosa: if (!open(PIPPO)) { die "Errore in open $PIPPO: $!"; } die "Errore in open $PIPPO: $!" unless open(PIPPO); open(PIPPO) or die "Errore in open $PIPPO: $!"; # PIPPO o morte! open(PIPPO) ? 'hi mom' : die "Errore in open $PIPPO: $!"; # un po' esotica, quest'ultima L'istruzione L'istruzione Se c'è un BLOCCO
Controllo di CicloIl comando RIGA: while (<STDIN>) { next RIGA if /^#/; # Scarta i commenti #... } Il comando RIGA: while (<STDIN>) { last RIGA if /^$/; # esci quando hai finito con l'intestazione # ... } Il comando Ad esempio, quando elaborate un file come /etc/termcap. Se le vostre righe di ingresso potessero terminare con backslash per indicare continuazione, vorreste saltare avanti e prendere il record successivo. while (<>) { chomp; if (s/\\$//) { $_ .= <>; redo unless eof(); } # ora si elabora $_ } che è una scorciatoia Perl per la versione più esplicita: RIGA: while (defined($riga = <ARGV>)) { chomp($riga); if ($riga =~ s/\\$//) { $riga .= <ARGV>; redo RIGA unless eof(); # non eof(ARGV)! } # ora si elabora $riga } Osservate che se ci fosse un blocco # ispirato da :1,$g/fred/s//WILMA/ while (<>) { ?(fred)? && s//WILMA $1 WILMA/; ?(barney)? && s//BETTY $1 BETTY/; ?(homer)? && s//MARGE $1 MARGE/; } continue { print "$ARGV $.: $_"; close ARGV if eof(); # riazzera $. reset if eof(); # riazzera ?pattern? } Se si sostituisce la parola Le istruzioni di controllo di ciclo non funzionano all'interno di
if (/pattern/) {{ last if /fred/; next if /barney/; # stesso effetto di "last", ma non documenta altrettanto bene # qui si fa qualcosa }} Questo comportamento si ha perché quel blocco, di per sé, agisce come un ciclo che viene eseguito una volta sola, consultate BLOCCHI base ed Istruzioni Switch. La forma
Cicli ForI cicli for ($i = 1; $i < 10; $i++) { # ... } è la stessa cosa di: $i = 1; while ($i < 10) { # ... } continue { $i++; } C'è una differenza minore: se le variabili sono dichiarate con Oltre al normale ciclo con l'indice di un array, $su_una_tty = -t STDIN && -t STDOUT; sub richiedi { print "si'? " if $su_una_tty } for ( richiedi(); <STDIN>; richiedi() ) { # fai qualcosa } Utilizzando for ( richiedi(); defined( $_ = <STDIN> ); richiedi() ) { # fai qualcosa }
Cicli ForeachIl ciclo La parola chiave Se un qualunque elemento di LISTA è un lvalue [valore utilizzabile
alla sinistra di un'assegnazione, NdT], potete modificarlo attraverso
VAR all'interno del ciclo. Di contro, se un qualsiasi elemento in LISTA
NON è un lvalue, qualsiasi tentativo di modificare quell'elemento
fallirà. In altre parole, la variabile indice in un ciclo Se una qualunque parte di LISTA è un array,
Esempi: for (@ary) { s/foo/bar/ } for my $elem (@elementi) { $elem *= 2; } for $contatore (10,9,8,7,6,5,4,3,2,1,'BOOM') { print $contatore, "\n"; sleep(1); } for (1..15) { print "Buon Natale\n"; } foreach $elemento (split(/:[\\\n:]*/, $ENV{TERMCAP})) { print "Elemento: $elemento\n"; } Ecco come un programmatore C potrebbe scrivere un particolare algoritmo in Perl: for (my $i = 0; $i < @ary1; $i++) { for (my $j = 0; $j < @ary2; $j++) { if ($ary1[$i] > $ary2[$j]) { last; # non si puo` andare su quello esterno :-( } $ary1[$i] += $ary2[$j]; } # ecco dove mi porta quel last } Ecco invece come potrebbe farlo un programmatore Perl più a suo agio con l'idioma: ESTERNO: for my $wid (@ary1) { INTERNO: for my $jet (@ary2) { next ESTERNO if $wid > $jet; $wid += $jet; } } Vedete quant'è più facile? È più pulito, sicuro e veloce.
È più pulito perché ha meno rumore. È più sicuro
perché se più tardi si aggiunge codice fra il ciclo interno e quello esterno,
il nuovo codice non verrà eseguito accidentalmente. Il
BLOCCHI base ed Istruzioni SwitchUn BLOCCO di per sé (etichettato o meno) è semanticamente equivalente ad
un ciclo che viene eseguito una volta. Per questo motivo potete
utilizzare una qualunque delle istruzioni di controllo di ciclo al suo
interno, per lasciare o far ripartire il blocco. (Osservate che
ciò NON vale per Il costrutto BLOCCO è particolarmente utile per realizzare strutture
SWITCH: { if (/^abc/) { $abc = 1; last SWITCH; } if (/^def/) { $def = 1; last SWITCH; } if (/^xyz/) { $xyz = 1; last SWITCH; } $niente = 1; } Non esite alcuna istruzione Ad ogni modo, a partire da Perl 5.8, per avere switch e use Switch; dopo di che si hanno switch e case. Non è veloce come potrebbe perché non è veramente parte del linguaggio (è realizzato utilizzando dei filtri sul codice sorgente), ma è disponibile e molto flessibile. In aggiunta al costrutto BLOCCO citato, potreste anche scrivere SWITCH: { $abc = 1, last SWITCH if /^abc/; $def = 1, last SWITCH if /^def/; $xyz = 1, last SWITCH if /^xyz/; $niente = 1; } (Non è, in realtà, strano come sembra una volta compreso che potete utilizzare ``operatori'' di controllo del ciclo all'interno di un'espressione. Si sta solo utilizzando l'operatore binario ``virgola'' in contesto scalare. Consultate perlop/``Comma Operator'' [``L'operatore virgola'', NdT]). o SWITCH: { /^abc/ && do { $abc = 1; last SWITCH; }; /^def/ && do { $def = 1; last SWITCH; }; /^xyz/ && do { $xyz = 1; last SWITCH; }; $niente = 1; } o formattato in modo che risalti di più come un'istruzione SWITCH: { /^abc/ && do { $abc = 1; last SWITCH; }; /^def/ && do { $def = 1; last SWITCH; }; /^xyz/ && do { $xyz = 1; last SWITCH; }; $niente = 1; } o SWITCH: { /^abc/ and $abc = 1, last SWITCH; /^def/ and $def = 1, last SWITCH; /^xyz/ and $xyz = 1, last SWITCH; $niente = 1; } o anche, orrore, if (/^abc/) { $abc = 1 } elsif (/^def/) { $def = 1 } elsif (/^xyz/) { $xyz = 1 } else { $niente = 1 } Un idioma comune per un'istruzione SWITCH: for ($dove) { /Nei Nomi delle Carte/ && do { push @flags, '-e'; last; }; /Ovunque/ && do { push @flags, '-h'; last; }; /Nelle Regole/ && do { last; }; die "valore sconosciuto per la variabile dove: `$dove'"; } Un altro approccio interessante per un'istruzione switch consiste
nel fare in modo che un blocco $amode = do { if ($flag & O_RDONLY) { "r" } # XXX: non e` 0? elsif ($flag & O_WRONLY) { ($flag & O_APPEND) ? "a" : "w" } elsif ($flag & O_RDWR) { if ($flag & O_CREAT) { "w+" } else { ($flag & O_APPEND) ? "a+" : "r+" } } }; O print do { ($flags & O_WRONLY) ? "write-only" : ($flags & O_RDWR) ? "read-write" : "read-only"; }; O se siete certi che tutte le clausole in #!/usr/bin/perl # prendi la pagina del file jargon in base al browser $dir = 'http://www.wins.uva.nl/~mes/jargon'; for ($ENV{HTTP_USER_AGENT}) { $page = /Mac/ && 'm/Macintrash.html' || /Win(dows )?NT/ && 'e/evilandrude.html' || /Win|MSIE|WebTV/ && 'm/MicroslothWindows.html' || /Linux/ && 'l/Linux.html' || /HP-UX/ && 'h/HP-SUX.html' || /SunOS/ && 's/ScumOS.html' || 'a/AppendixB.html'; } print "Location: $dir/$page\015\012\015\012"; Questo tipo di istruzione switch funziona solamente quando sapete che
le clausole Potreste anche prendere in considerazione lo scrivere una hash contenente
riferimenti a subroutine invece di realizzare un'instruzione
GotoSebbene non sia adatta ai deboli di cuore, Perl supporta un'istruzione
La forma La forma goto(("PIPPO", "PLUTO", "TOPOLINO")[$i]); La forma In quasi tutti i casi come questo, è di solito un'idea di gran lunga migliore
utilizzare i meccanismi di controllo di flusso dati da
POD: Documentazione ImmersaPerl ha un meccanismo per inframmezzare la documentazione con il codice sorgente. Nei punti in cui si aspetta l'inizio di una nuova istruzione, se il compilatore incontra una riga che comincia con un segno uguale ed una parola, come questa: =head1 Ecco che arrivano i Pod! allora il testo nella riga e tutto quello che segue fino ad una riga
che comincia con Ciò vi consente di inframmezzare liberamente codice e documentazione, come in =item spippola($) La funzione spippola() si comportera` nella piu` spettacolare delle forme che possiate mai immaginare, senza nemmeno escludere forme pirotecniche cibernetiche. =cut torniamo al compilatore, niente di questa roba pod! sub spippola($) { my $cosetta = shift; # ......... } Osservate che i traduttori pod dovrebbero guardare solo ai paragrafi che iniziano con una direttiva pod (rende più semplice il parsing), laddove il compilatore di fatto sa rilevare delle eccezioni pod anche nel bel mezzo di un paragrafo. Questo signifca che la roba segreta che segue verrà ignorata sia dal compilatore che dai traduttori. $a=3; =roba segreta warn "Ne' CODICE ne' POD!?" =cut indietro print "preso $a\n"; Probabilmente, però, non dovreste contare troppo sul fatto che l'istruzione
Si possono anche utilizzare le direttive pod per commentare rapidamente una sezione di codice.
Buoni Vecchi Commenti (No!)Perl può elaborare direttive di riga, molto similmente al preprocessore C.
Utilizzando questo meccanismo, è possibile controllare l'idea che Perl ha
dei nomi dei file e dei numeri di riga nei messaggi di errore o di avviso
(specialmente per quelle stringhe che sono elaborate con # esempio: '# riga 42 "nuovo_nomefile.plx"' /^\# \s* line \s+ (\d+) \s* (?:\s("?)([^"]+)\2)? \s* $/x laddove C'è una cosa piuttosto ovvia da cui guardarsi quando si utilizza la direttiva
Ecco alcuni esempi che dovreste essere in grado di digitare nella vostra shell di comando: % perl # line 200 "bzzzt" # il `#' nella riga precedente deve essere il primo carattere nella riga die 'pippo'; __END__ pippo at bzzzt line 201. % perl # line 200 "bzzzt" eval qq[\n#line 2001 ""\ndie 'pippo']; print $@; __END__ pippo at - line 2001. % perl eval qq[\n#line 200 "pippo pluto"\ndie 'pippo']; print $@; __END__ pippo at pippo pluto line 200. % perl # line 345 "miao" eval "\n#riga " . __LINE__ . ' "' . __FILE__ ."\"\ndie 'pippo'"; print $@; __END__ pippo at miao line 345.
TRADUZIONE
VersioneLa versione su cui si basa questa traduzione è ottenibile con: perl -MPOD2::IT -e print_pod perlsyn Per maggiori informazioni sul progetto di traduzione in italiano si veda http://pod2it.sourceforge.net/ .
TraduttoreTraduzione a cura di kral e Flavio Poletti.
RevisoreRevisione a cura di dree. Mon Jun 11 22:02:19 2012 |