=head1 NOME X perlsyn - La sintassi del Perl =head1 DESCRIZIONE Un 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 E un linguaggio B [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 E un'importante parte della sintassi. Molti degli elementi sintattici del Perl sono B. 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 cercherE di capire cosa intendete. Questo E conosciuto come B [Fa quello che intendo, NdT], abbreviato B. CiE permette ai programmatori di essere B e di scrivere il codice in uno stile a loro confortevole. Il Perl B 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. CosE se avete giE programmato con un altro linguaggio troverete frammenti familiari in Perl. Spesso funzionano allo stesso modo, ma consultate L per informazioni su cosa differiscono. =head2 Dichiarazioni X X X X Le 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 (C) finchE non le viene assegnato un valore definito, cioE qualsiasi valore divero da C. Quando E usato come numero, C viene considerato come C<0>; quando E usato come stringa viene considerato la stringa vuota, C<"">; e quando viene utilizzato come riferimento che non E stato ancora assegnato, viene considerato come errore. Se abilitate i I [letterlmente avvertimenti, con C, NdT], vi verrE notificato l'uso di un valore non inizializzato, ogni volta che tratterete C come stringa o come numero. Beh, di solito. Contesti booleani come: my $a; if ($a) {} sono esenti da avvertimenti (perchE sono casi in cui importa la veridicitE piuttosto che la definizione). Operatori come C<++>, C<-->, C<+=>, C<-=> e C<.=>, quando operano su variabili indefinite come: my $a; $a++; sono anch'essi esenti da questi avvertimenti. Una dichiarazione puE 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 C dovete assicurarvi che la definizione del vostro formato o della subroutine sia nello stesso blocco del C per essere in grado di accedere a queste variabili private. 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 C, cosE: X sub mionome; $io = mionome $0 or die "impossibile utilizzare mionome"; Va notato che mionome() funziona come operatore di lista, non come operatore unario; quindi, in questo caso, state attenti ad usare C invece di C<||>. Comunque, se dichiaraste la subroutine come C, allora C funzionerebbe come operatore unario, cosE sia C che C<||> andrebbero bene. Le dichiarazioni delle subroutine possono anche essere caricate con l'istruzione C, oppure sia caricate che importate nel vostro spazio dei nomi con l'istruzione C. Consultate L per ulteriori dettagli. Una sequenza di istruzioni puE 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 realtE hanno degli effetti sia durante la compilazione che durante l'esecuzione. =head2 Commenti X X<#> Il testo, dal carattere C<"#"> sino alla fine della riga, E un commento e viene ignorato. Le eccezioni includono C<"#"> all'interno di una stringa o di un'espressione regolare. =head2 Istruzioni Semplici X X X X<;> L'unico tipo di istruzione semplice E 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 E opzionale. (Un punto e virgola E tuttavia incoraggiato se il blocco E lungo piE di una riga, cosE potete eventualmente aggiungere un'altra riga). Da notare che ci sono operatori come C e C che sembrano istruzioni composte, ma non lo sono (sono solo TERMINI in un espressione), e perciE necessitano di un indicatore di terminazione explicito se sono usati come ultimo elemento in una espressione. =head2 VeritE e FalsitE X X X X X X X X<0> Il numero 0, le stringhe C<'0'> e C<''>, la lista vuota C<()> e C risultano tutti falsi in un contesto booleano. Tutti gli altri valori sono veri. La negazione di un valore vero attraverso C o C restituisce un valore falso speciale. Quando valutato come stringa viene trattato come C<''>, ma come numero E considerato pari a 0. =head2 Modificatori di Istruzione X X X X X X X X Qualunque instruzione semplice puE eventualmente essere seguita da un I 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'C che segue il modificatore E detta "condizione". La sua veridicitE o falsitE determina il modo in cui il modificatore dovrE comportarsi. C esegue l'istruzione una volta I e solo se la condizione E vera. C E l'opposto, ed esegue l'istruzione I l'istruzione risulti vera (ossia, se la condizione E falsa). print "I basset hound hanno lunghe orecchie" if length $orecchie >= 10; vai_fuori() and gioca() unless $sta_piovendo; Il modificatore C E un iteratore: esegue l'istruzione una volta per ogni elemento nella LISTA (con C<$_> che diventa un alias di ciascun elemento, volta per volta). print "Ciao $_!\n" foreach qw(mondo Dolly infermiera); C ripete l'istruzione I> la condizione E vera. C fa l'opposto, cioE ripete l'istruzione fermandosi quando la condizione risulta vera. # Ciascuna istruzione conta da 0 a 10. print $i++ while $i <= 10; print $j++ until $j > 10; I modificatori C e C hanno la tipica semantica del "ciclo C" (la condizione E valutata per prima), eccetto quando E applicata ad un BLOCCO C (oppure all'uso deprecato dell'istruzione C-SUBROUTINE), nel qual caso il blocco viene eseguito una volta prima che sia valutata la condizione. CosE potete scrivere cicli come: do { $riga = ; # ... } until $riga eq ".\n"; Vedete L. Osservate inoltre che le istruzioni di controllo di ciclo descritte in seguito I funzioneranno con questo costrutto, perchE i modificatori non accettano etichette di ciclo. Spiacenti. Potete sempre mettere un altro blocco all'interno (per C) o all'esterno (per C) per fare questo genere di cose. Per C basta raddoppiare le parentesi graffe: X X X do {{ next if $x == $y; # qui si fa qualcosa }} until $x++ > $z; Per C dovete essere piE elaborati: X CICLO: { do { last if $x = $y**2; # qui si fa qualcosa } while $x++ <= $z; } B Il comportamento di un'istruzione C modificata da un modificatore di istruzione o da un costrutto di ciclo (ad esempio, C) E B. Il valore della variabile C puE essere C, un qualunque valore assegnato in precedenza, o forse qualsiasi altra cosa. Non ci contate. Versioni future di perl potrebbero fare cose differenti rispetto alla versione che state utilizzando ora. Occhio ai dragoni. X =head2 Istruzioni Composite X X X X X X<{> X<}> X X X X X X X In Perl, una sequenza di istruzioni che definisce uno I viene chiamata blocco. A volte un blocco E delimitato dal file che lo contiene (nel caso di un file richiesto [con C, NdT], o il programma nella sua interezza), ed a volte un blocco E delimitato dalla lunghezza di una stringa (nel caso di una C). In generale, perE, un blocco E delimitato da parentesi graffe. Chiameremo questo costrutto sintattico un BLOCCO. Le istruzioni composite 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. CiE significa che le parentesi graffe sono I -- 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 C E banale. PoichE i BLOCCHI sono sempre circondati da parentesi graffe, non c'E mai ambiguitE su quale C sia associato ad un particolare C. Se utilizzate C al posto di C, il senso del test E invertito. L'istruzione C esegue il blocco finchE l'espressione E vera (ossia, non viene valutata come la stringa nulla C<""> o C<0> o C<"0"> [o anche C, NdT]). L'istruzione C esegue il blocco finchE l'espressione E falsa. L'ETICHETTA E opzionale e, se presente, consiste in un identificatore seguito da un carattere due-punti. L'ETICHETTA identifica il ciclo per le istruzioni di controllo dei cicli C, C e C. Se l'ETICHETTA viene omessa, l'istruzione di controllo del ciclo si riferisce al ciclo piE interno che la racchiude. Tutto ciE puE implicare uno sguardo dinamico allo I di chiamata in esecuzione per trovare l'ETICHETTA giusta. Un comportamento cosE disperato produce un avvertimento ["warning", NdT] se utilizzate la direttiva C o l'opzione C<-w>. Se c'E un BLOCCO C, viene sempre eseguito immediatamente prima che la condizione venga valutata di nuovo. Per questo motivo, puE essere utilizzato per incrementare la variabile di un ciclo, anche quando il ciclo viene fatto continuare con un'istruzione C. =head2 Controllo di Ciclo X X X X X X Il comando C fa partire l'iterazione successiva del ciclo: RIGA: while () { next RIGA if /^#/; # Scarta i commenti #... } Il comando C esce immediatamente dal ciclo in questione. Il blocco C, se presente, non viene eseguito: RIGA: while () { last RIGA if /^$/; # esci quando hai finito con l'intestazione # ... } Il comando C fa ripartire il ciclo senza valuatare la condizione di nuovo. Il blocco C, se presente, I viene eseguito. Questo comando viene normalmente utilizzato da programmi che vogliono mentire a se stessi su quanto E stato appena inserito. Ad esempio, quando elaborate un file come F. Se le vostre righe di ingresso potessero terminare con I per indicare continuazione, vorreste saltare avanti e prendere il record successivo. while (<>) { chomp; if (s/\\$//) { $_ .= <>; redo unless eof(); } # ora si elabora $_ } che E una scorciatoia Perl per la versione piE esplicita: RIGA: while (defined($riga = )) { chomp($riga); if ($riga =~ s/\\$//) { $riga .= ; redo RIGA unless eof(); # non eof(ARGV)! } # ora si elabora $riga } Osservate che se ci fosse un blocco C in questo codice, verrebbe eseguito solo in corrispondenza delle righe scartate dall'espressione regolare (poichE C salta il blocco C). Un blocco C viene spesso utilizzato per riazzerare i contatori di riga o dei match di singoli C: # 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 C a C il senso del test E invertito, ma la condizione viene sempre verificata prima della prima iterazione. Le istruzioni di controllo di ciclo non funzionano all'interno di C o C, poichE questi non sono cicli. Potete perE raddoppiare le parentesi graffe per renderli tali. 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 perchE quel blocco, di per sE, agisce come un ciclo che viene eseguito una volta sola, consultate L<"BLOCCHI base ed Istruzioni Switch">. La forma C, disponibile in Perl 4, non esiste piE. Rimpiazzate ogni occorrenza di C con C. =head2 Cicli For X X I cicli C stile C in Perl funzionano come il corrispondente ciclo C; ciE significa che questo: for ($i = 1; $i < 10; $i++) { # ... } E la stessa cosa di: $i = 1; while ($i < 10) { # ... } continue { $i++; } C'E una differenza minore: se le variabili sono dichiarate con C nella sezione di inizializzazione del C, lo I lessicale di queste variabili coincide con il ciclo C (il corpo del ciclo e le sezioni di controllo). X Oltre al normale ciclo con l'indice di un array, C puE prestarsi a molte altre applicazioni interessanti. Eccone una che evita il problema in cui vi trovate se effettuate esplicitamente il test di fine file su un descrittore di file interattivo, il che farebbe sembrare bloccato il programma. X X X $su_una_tty = -t STDIN && -t STDOUT; sub richiedi { print "si'? " if $su_una_tty } for ( richiedi(); ; richiedi() ) { # fai qualcosa } Utilizzando C (o la forma ad operatore, C<< >>) come condizionali per un ciclo C E una scorciatoia per quanto segue. Questo comportamento coincide con quello di una condizione in un ciclo C. X X<< <> >> for ( richiedi(); defined( $_ = ); richiedi() ) { # fai qualcosa } =head2 Cicli Foreach X X Il ciclo C itera su una normale lista ed imposta la variabile VAR come incarnazione di ciascun elemento della lista, in sequenza. Se la variabile E preceduta dalla parola chiave C, allora essa ha lo I di un lessicale, ed E pertanto visibile solo all'interno del ciclo. Altrimenti, la vaiabile E implicitamente locale al ciclo e viene ripristinata al suo valore originale una volta usciti dal ciclo. Se la variabile era stata precedentemente dichiarata con C, viene utilizzata quella variabile invece che quella globale, ma E sempre localizzata al ciclo. Questa localizzazione implicita avviene I in un ciclo C. X X La parola chiave C E in realtE un sinonimo per la parola chiave C, di modo che potete utilizzare C per privilegiare la leggibilitE o C per maggiore brevitE. (O perchE la shell Bourne potrebbe esservi piE familiare di I, quindi scrivere C verrebbe piE naturale). Se VAR E omessa, C<$_> viene impostata a ciascun valore. X<$_> Se un qualunque elemento di LISTA E un I [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 E un I, qualsiasi tentativo di modificare quell'elemento fallirE. In altre parole, la variabile indice in un ciclo C E un alias implicito per ciascun elemento nella lista su cui state iterando. X Se una qualunque parte di LISTA E un array, C rimarrE decisamente confuso se aggiungete o rimuovete elementi all'interno del corpo del ciclo, ad esempio utilizzando C. Per questo motivo, non fatelo. X C, probabilmente, non farE quel che vi aspettate se VAR E una variabile su cui E stata chiamata C o se E un'altra variabile speciale. Non fate nemmeno questo. 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 piE 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'E piE facile? E piE pulito, sicuro e veloce. E piE pulito perchE ha meno rumore. E piE sicuro perchE se piE tardi si aggiunge codice fra il ciclo interno e quello esterno, il nuovo codice non verrE eseguito accidentalmente. Il C itera esplicitamente il ciclo esterno invece che ridursi a terminare quello interno. Ed E piE veloce perchE Perl esegue un'istruzione C piE rapidamente di quanto farebbe un ciclo C equivalente. =head2 BLOCCHI base ed Istruzioni Switch X X X Un BLOCCO di per sE (etichettato o meno) E 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 ciE I vale per C e C, o contrariamente al credo popolare per i blocchi C, che I contano come cicli). Il blocco C E opzionale. Il costrutto BLOCCO E particolarmente utile per realizzare strutture C [istruzione C che marca una fra piE parti di codice differenti a seconda del valore di un'espressione, NdT]. 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 C ufficiale in Perl, perchE ci sono giE molti modi per scrivere qualcosa di equivalente. Ad ogni modo, a partire da Perl 5.8, per avere I e C si puE utilizzare l'estensione Switch e dichiarare: use Switch; dopo di che si hanno switch e case. Non E veloce come potrebbe perchE non E veramente parte del linguaggio (E realizzato utilizzando dei filtri sul codice sorgente), ma E 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 E, in realtE, 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 L ["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 piE come un'istruzione C "propria": 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 C consiste nell'utilizzare l'aliasing di C per effetture assegnazioni temporanee a C<$_> ed ottenere un matching conveniente: 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 C restituisca il valore corretto: $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 C<&&> sono vere, potete utilizzare qualcosa come quello che segue, che "cambia" in base al valore della variabile di ambiente C. #!/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 C<&&> saranno vere. Se non siete sicuri, dovreste affidarvi all'esempio precedente con C. Potreste anche prendere in considerazione lo scrivere una hash contenente riferimenti a subroutine invece di realizzare un'instruzione C. =head2 Goto X Sebbene non sia adatta ai deboli di cuore, Perl supporta un'istruzione C. Esiste in tre forme: C-ETICHETTA, C-ESPRESSIONE e C-&NOME. Un'etichetta di ciclo non costituisce, in realtE, un valido obiettivo per una C; E solo il nome del ciclo. La forma C-ETICHETTA trova l'istruzione etichettata con ETICHETTA e riprende l'esecuzione da lE. Non puE essere utilizzata per andare in un qualunque costrutto che richieda inizializzazione, come una subroutine o un ciclo C. Non puE nemmeno essere utilizzata per andare in un costrutto che viene ottimizzato. PuE invece essere usata per andare praticamente in qualsiasi posto che si trovi nello scope dinamico, inclusa l'uscita dalle subroutine. Ma di solito E meglio utilizzare altri costrutti come C o C. L'autore di Perl non ha mai sentito il bisogno di utilizzare questa forma di C (in Perl perlomeno -- in C E un'altra storia). La forma C-ESPRESSIONE si aspetta il nome di un'etichetta, il cui scope verrE risolto dinamicamente. Questo consente di avere dei C calcolati come in FORTRAN, ma non E nesessariamente raccomandato se cercate di ottimizzare il codice rispetto alla manutenibilitE: goto(("PIPPO", "PLUTO", "TOPOLINO")[$i]); La forma C-&NOME E estremamente magica, e sostituisce una chiamata alla subroutine nominata al posto della subroutine attualmente in esecuzione. Questo meccanismo viene utilizzato dalle subroutine C che vogliono caricare un'altra subroutine e far finta che tale altra subroutine sia stata chiamata sin dall'inizio (eccetto che eventuali modifiche a C<@_> nella subroutine corrente siano propagate anche nell'altra). Dopo una C, nemmeno C sarE in grado di dire che questa routine E stata chiamata prima. In quasi tutti i casi come questo, E di solito un'idea di gran lunga migliore utilizzare i meccanismi di controllo di flusso dati da C, C o C piuttosto che abbassarsi al livello di C. Per certe applicazioni, la coppia di I e C [terminologia utilizzata per parlare della gestione delle eccezioni in molti linguaggi, fra cui C++ e Java, NdT] fornita da C e C per l'elaborazione delle eccezioni puE risultare un approccio prudente. =head2 POD: Documentazione Immersa X X Perl 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 C<=cut> (riga compresa) sarE ignorato. Il formato del testo incluso E descritto in L. CiE 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 piE 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 verrE ignorata sia dal compilatore che dai traduttori. $a=3; =roba segreta warn "Ne' CODICE ne' POD!?" =cut indietro print "preso $a\n"; Probabilmente, perE, non dovreste contare troppo sul fatto che l'istruzione C qui sopra verrE eliminata come pod per sempre. Non tutti i traduttori di pod si comportano bene a questo proposito, e forse il compilatore diverrE piE bizzoso. Si possono anche utilizzare le direttive pod per commentare rapidamente una sezione di codice. =head2 Buoni Vecchi Commenti (No!) X X X X<#> X X Perl puE elaborare direttive di riga, molto similmente al preprocessore C. Utilizzando questo meccanismo, E 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 C). La sintassi per questo meccanismo E la stessa che per la maggior parte dei preprocessori C: aderisce all'espressione regolare # esempio: '# riga 42 "nuovo_nomefile.plx"' /^\# \s* line \s+ (\d+) \s* (?:\s("?)([^"]+)\2)? \s* $/x laddove C<$1> rappresenta il numero di riga per la prossima riga, e C<$3> rappresenta il nome del file opzionale (specificato con o senza virgolette). C'E una cosa piuttosto ovvia da cui guardarsi quando si utilizza la direttiva C: i debugger ed i profiler [programmi che analizzano le prestazioni delle varie sezioni del programma, NdT] mostreranno solo l'ultima riga riga sorgente come presente ad un particolare numero di riga in un dato file. Dovete prestare attenzione a non generare delle collisioni nei numeri di riga nel codice su cui avrete poi voglia di effettuare il debug. 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. =head1 TRADUZIONE =head2 Versione La versione su cui si basa questa traduzione E ottenibile con: perl -MPOD2::IT -e print_pod perlsyn Per maggiori informazioni sul progetto di traduzione in italiano si veda L . =head2 Traduttore Traduzione a cura di kral e Flavio Poletti. =head2 Revisore Revisione a cura di dree. =cut