index | project | pods | responsabili

NOME

perlop - Operatori Perl e precedenze


DESCRIZIONE

Precedenza e associatività degli operatori

La precedenza e l'associatività degli operatori in Perl funzionano grossomodo come funzionano in matematica.

Precedenza degli operatori significa che alcuni operatori vengono valutati prima di altri. Ad esempio, in 2 + 4 * 5, la moltiplicazione ha una precedenza maggiore, così 4 * 5 viene valutato per primo, risultando in 2 + 20 == 22 e non 6 * 5 == 30.

La Associatività degli operatori > definisce cosa accade quando uno stesso operatore viene utilizzato più volte: ossia, se viene valutata prima l'operazione a sinistra o prima quella a destra. Ad esempio, in 8 - 4 - 2, la sottrazione è associativa a sinistra, così Perl valuta l'espressione da sinistra a destra. 8 - 4 viene valutato prima, rendendo l'operazione 4 - 2 == 2 e non 8 - 2 == 6.

Gli operatori Perl hanno le seguenti associatività e precedenze, elencate dalla precedenza più alta a quella più bassa. Gli operatori presi in prestito dal C mantengono fra di loro la stessa relazione di precedenza, anche nei casi in cui la precedenza del C è leggermente inappropriata (questo rende più facile imparare il Perl ai programmatori C). Con rarissime eccezioni, tutti questi operatori operano soltanto su valori scalari, non su array.

    sinistra    termini e operatori su liste (associativita` sinistra)
    sinistra    ->
    nonassoc    ++ --
    destra  **
    destra  ! ~ \ e + e - unari
    sinistra    =~ !~
    sinistra    * / % x
    sinistra    + - .
    sinistra    << >>
    nonassoc    operatori unari con nome
    nonassoc    < > <= >= lt gt le ge
    nonassoc    == != <=> eq ne cmp
    sinistra    &
    sinistra    | ^
    sinistra    &&
    sinistra    ||
    nonassoc    ..  ...
    destra  ?:
    destra  = += -= *= ecc.
    sinistra    , =>
    nonassoc    operatori su liste (ass. destra)
    destra  not
    sinistra    and
    sinistra    or xor

Nelle sezioni seguenti, questi operatori sono documentati in ordine di precedenza.

Molti operatori possono essere sottoposti ad overload per oggetti. Si veda overload.

Termini e Operatori di Lista (Associatività a Sinistra)

Un TERMINE ha in Perl la precedenza più alta. Sono termini le variabili, le virgolette e gli operatori che si comportano come virgolette, qualunque espressione fra parentesi e ogni funzione i cui argomenti sono racchiusi fra parentesi. In realtà non esistono propriamente funzioni in tal senso, ma operatori di lista e operatori unari che si comportano come funzioni quando vengono messe le parentesi attorno agli argomenti. Questi operatori sono tutti documentati in perlfunc.

Se un qualunque operatore di lista (print(), ecc.) o un qualunque operatore unario (chdir(), ecc.) è seguito da una parentesi aperta come simbolo successivo, l'operatore e gli argomenti fra le parentesi vengono valutati con la precedenza più alta, come una normale chiamata di funzione.

In assenza di parentesi, la precedenza degli operatori di lista come print, sort, o chmod è molto alta o molto bassa a seconda che si consideri ciò che si trova a sinistra o a destra dell'operatore. Ad esempio, in

    @ary = (1, 3, sort 4, 2);
    print @ary;     # stampa 1324

le virgole a destra di sort vengono valutate prima dell'ordinamento, ma le virgole a sinistra vengono valutate dopo. In altri termini, gli operatori di lista tendono a mangiarsi tutti gli argomenti che li seguono, e si comportano dunque come un semplice TERMINE nei confronti dell'espressione che li precede. Occorre fare attenzione con le parentesi:

    # Queste righe valutano exit prima di print:
    print($pippo, exit);    # Decisamente non e` cio` che si vuole.
    print $pippo, exit;     # Neanche questo.
    # Queste eseguono print prima di valutare exit:
    (print $pippo), exit;   # Questo e` cio` che si vuole.
    print($pippo), exit;    # Oppure questo.
    print ($pippo), exit;   # O anche questo.

Si noti anche che

    print ($pippo & 255) + 1, "\n";

probabilmente non fa ciò che di primo acchito ci si aspetterebbe. Le parentesi racchiudono la lista di argomenti per print, che viene valutato (e stampa il risultato di $pippo & 255). Poi viene aggiunto uno al valore restituito da print (solitamente 1). Il risultato è una cosa simile a:

    1 + 1, "\n";    # Ovviamente non e` quello che si intendeva.

Per ottenere il risultato corretto bisogna scrivere:

    print(($pippo & 255) + 1, "\n");

Per un ulteriore approfondimento si veda anche Operatori unari con nome.

Vengono interpretati come termini anche i costrutti do {} ed eval{}, le chiamate a subroutine e metodi, e i costruttori anonimi [] e {}.

Si veda anche Operatori per il quote ed equivalenti verso la fine di questa sezione, e Operatori di I/O.

L'Operatore Freccia >>

``->'' è un operatore infisso di dereferenziazione, come in C e C++. Se sul lato destro si trova un qualcosa come [...], {...}, o (...), allora il lato sinistro deve essere un riferimento concreto [hard reference, NdR] o simbolico [symbolic reference, NdR] a, rispettivamente, un array, un hash, o una subroutine (o, tecnicamente parlando, una locazione in grado di contenere un riferimento concreto, se si tratta di un riferimento ad array o hash utilizzato in un assegnamento). Si vedano perlreftut e perlref.

In caso contrario, il lato destro è il nome di un metodo, o una variabile scalare semplice contenente o il nome del metodo o un riferimento a subroutine, e il lato sinistro deve essere un oggetto (un riferimento a cui è stato applicato bless) oppure un nome di una classe (ossia il nome di un package). Si veda in questo caso perlobj.

Auto-incremento e Auto-decremento

``++'' e ``--'' funzionano come in C. Ossia, se posti prima di una variabile, incrementano o decrementano la variabile di uno prima di restituirne il valore, mentre se posti dopo, la incrementano o decrementano dopo averne restituito il valore.

    $i = 0;  $j = 0;
    print $i++;  # stampa 0
    print ++$j;  # stampa 1

Si noti che, come in C, Perl non definisce quando la variabile è incrementata o decrementata. Basta sapere che sarà fatto una volta prima o dopo il valore restituito. Questo significa anche che modificare una variabile due volte nella stessa istruzione porterà ad un comportamento indefinito. Si evitino istruzioni come:

    $i = $i ++;
    print ++ $i + $i ++;

Perl non garantisce quale sia il risultato delle istruzioni di cui sopra.

L'operatore di auto-incremento ha un po' di magia in più. Se viene incrementata una variabile numerica, o che sia stata usata in contesto numerico, si ottiene un normale incremento. Se, tuttavia, la variabile è stata utilizzata solo in un contesto di stringa fin dalla sua impostazione, e contiene un valore che non è la stringa vuota e corrisponde allo schema /^[a-zA-Z]*[0-9]*\z/, allora l'incremento viene fatto considerandola stringa, conservando ciascun carattere entro il suo intervallo, con eventuale riporto al carattere successivo:

    print ++($pippo = '99');    # stampa '100'
    print ++($pippo = 'a0');    # stampa 'a1'
    print ++($pippo = 'Az');    # stampa 'Ba'
    print ++($pippo = 'zz');    # stampa 'aaa'

undef viene sempre trattato come numerico, e in particolare viene modificato in 0 prima dell'incremento (in modo che un post-incremento di un valore indefinito restituisca 0 invece di undef).

L'operatore di auto-decremento non è magico.

Elevazione a Potenza

L'operatore binario ``**'' è l'operatore di elevazione a potenza. Ha una associatività maggiore persino del meno unario, quindi -2**4 vuol dire -(2**4), non (-2)**4. È implementato utilizzando la funzione C pow(3), che internamente utilizza dei numeri in virgola mobile.

Operatori unari simbolici

Il ``!'' unario effettua una negazione logica, ossia ``non''. Per una versione dello stesso operatore con precedenza più bassa si veda anche not.

Il ``-'' unario effettua una negazione aritmetica se l'operando è numerico. Se l'operando è un identificatore, viene restituita una stringa che consiste nel segno meno seguito dall'identificatore. Diversamente, se la stringa inizia con un piè o un meno, viene restituita una stringa che inizia con il segno opposto. Un effetto di tali regole è che -pippo è equivalente alla stringa "-pippo". Se, però, la stringa comincia con con carattere non alfabetico (a parte + o -), Perl proverà a convertirla in un valore numerico ed effettuare la negazione aritmetica. Se la stringa non può essere convertita correttamente in un valore numerico, Perl emetterà l'avviso Argument ``the string'' isn't numeric in negation (-) at ... [L'argomento ``stringa'' non è numerico nella negazione (-) alla riga..., NdT].

Il ``~'' unario effettua una negazione bit a bit, ossia il complemento ad 1. Ad esempio, 0666 & ~027 è uguale a 0640 (si veda anche Aritmetica Intera e Operatori bit a bit su stringhe). Va notato che la dimensione in bit dei valori restituiti dipende dalla piattaforma: ~0 è lungo 32 bit su piattaforme a 32 bit, ma 64 bit su piattaforme a 64 bit; quindi, se ci si aspetta un certo numero di bit, si ricordi di utilizzare l'operatore & per rimuovere i bit in eccesso.

Il ``+'' unario non ha alcun effetto, neanche sulle stringhe. Ha una utilità sintattica per separare un nome di funzione da un'espressione tra parentesi che sarebbe altrimenti interpretata come lista dei parametri della funzione (si vedano gli esempi sopra alla voce Termini e operatori di lista (associatività a sinistra)).

Il ``\'' unario crea un riferimento a tutto ciò che segue. Si vedano perlreftut e perlref. Quest'operazione non va confusa con l'utilizzo della backslash all'interno di stringhe, per quanto entrambe le forme esprimono il concetto di proteggere ciò che segue dall'interpolazione del loro valore.

Operatori di match

Il ``=~'' binario effettua un pattern match su un'espressione scalare. Di default, alcune operazioni agiscono su, o modificano, la stringa contenuta in $_. Tramite questo operatore è possibile compiere l'operazione su un'altra stringa. L'argomento di destra è un pattern di ricerca, sostituzione o traslitterazione. L'argomento di sinistra è ciò su cui si intende effettuare la ricerca, sostituzione o traslitterazione invece del default $_. Quando utilizzato in contesto scalare, il valore restituito indica generalmente il successo dell'operazione. Il comportamento in contesto di lista dipende dalla singola operazione. Per i dettagli si veda Operatori Quote-Like per Espressioni Regolari.

Se l'argomento di destra è un'espressione invece di un pattern di ricerca, sostituzione o traslitterazione, viene interpretato come pattern di ricerca a tempo di esecuzione.

Il ``!~'' è come ``=~'', solo che il valore restituito viene logicamente negato.

Operatori moltiplicativi

Il ``*'' binario moltiplica due numeri.

Il ``/'' binario divide due numeri.

Il ``%'' binario calcola il modulo di due numeri. Dati gli operandi interi $a e $b: se $b è positivo, $a % $b è $a meno il multiplo maggiore di $b che non è superiore ad $a. Se $b è negativo, $a % $b è $a meno il multiplo minore di $b che non è minore di $a (ossia il risultato sarà minore o uguale a zero). Va notato che se si sta utilizzando la direttiva integer, l'operatore ``%'' utilizza direttamente il corrispondente operatore C, come questo viene implementato dal vostro compilatore. Questo significa che il risultato con operandi negativi non è ben definito, ma l'esecuzione sarà più veloce.

Il ``x'' binario è l'operatore di ripetizione. In contesto scalare, o se l'operando di sinistra non è posto fra parentesi, restituisce una stringa composta dell'operando di sinistra ripetuto il numero di volte specificato dall'operando di destra. In contesto di lista, se l'operando di sinistra è posto fra parentesi, ripete la lista. Se l'operando di destra è zero o negativo, restituisce una stringa vuota o una lista vuota, a seconda del contesto.

    print '-' x 80;     # stampa una riga di trattini
    print "\t" x ($tab/8), ' ' x ($tab%8);  # [sostituisce spazi con tab]
    @uni = (1) x 80;        # una lista di 80 '1'
    @uni = (5) x @uni;      # imposta tutti gli elementi a 5

Operatori di addizione

Il ``+'' binario restituisce la somma di due numeri.

Il ``-'' binario restituisce la differenza di due numeri.

Il ``.'' binario concatena due stringhe.

Operatori di shift >> > >>>

Il ``<<'' binario restituisce il valore dell'operando di sinistra spostato a sinistra del numero di bit specificato dall'operando di destra. Gli operandi devono essere interi (Si veda anche Aritmetica intera).

Il ``>>'' binario restituisce il valore dell'operando di sinistra spostato a destra del numero di bit specificato dall'operando di destra. Gli operandi devono essere interi (Si veda anche Aritmetica intera).

Si noti che sia ``<<'' che ``>>'' sono implementati in Perl utilizzando direttamente i corrispondenti operatori C. Se si sta utilizzando use integer (si veda Aritmetica intera) vengono utilizzati gli interi con segno del C, altrimenti vengono utilizzati interi senza segno. In entrambi i casi, l'implementazione non genererà risultati che siano maggiori della dimensione degli interi con i quali il Perl è stato compilato (32 o 64 bit).

Il risultato di oltrepassare il limite consentito per gli interi non è definito, poiché non è definito neanche in C. In altre parole, usando interi a 32 bit, il risultato di 1 << 32 è indefinito. Anche lo shift di un numero negativo di bit è indefinito.

Operatori unari con nome

I vari operatori unari con nome sono trattati come funzioni con un argomento, con le parentesi opzionali.

Se un qualunque operatore di lista (print(), ecc.) o qualunque operatore unario (chdir(), ecc.) È seguito da una parentesi come simbolo successivo, l'operatore e gli argomenti dentro le parentesi sono interpretati come a precedenza maggiore, proprio come normali chiamate di funzione. Per esempio, dato che gli operatori unari con nome hanno precedenza maggiore di ||:

    chdir $pippo    || die;   # (chdir $pippo) || die
    chdir($pippo)   || die;   # (chdir $pippo) || die
    chdir ($pippo)  || die;   # (chdir $pippo) || die
    chdir +($pippo) || die;   # (chdir $pippo) || die

ma, dato che * ha precedenza maggiore rispetto agli operatori con nome:

    chdir $pippo * 20;      # chdir ($pippo * 20)
    chdir($pippo) * 20;     # (chdir $pippo) * 20
    chdir ($pippo) * 20;    # (chdir $pippo) * 20
    chdir +($pippo) * 20;   # chdir ($pippo * 20)
    rand 10 * 20;       # rand (10 * 20)
    rand(10) * 20;      # (rand 10) * 20
    rand (10) * 20;     # (rand 10) * 20
    rand +(10) * 20;    # rand (10 * 20)

Per quanto riguarda la precedenza, gli operatori di test sui file, come -f, -M, ecc. sono trattati come gli operatori unari con nome, ma non seguono le regole di funzionamento delle parentesi. Ciò significa, per esempio, che -f($file).``.bak''> è equivalente a -f "$file.bak".

Si veda anche Termini e Operatori Lista (a sinistra).


=head2 Operatori di confronto
X<relational operator> X<operator, relational>

L'operatore binario ``<'' restituisce un valore vero se l'argomento a sinistra è numericamente minore dell'argomento a destra. >

L'operatore binario ``>'' restituisce un valore vero se l'argomento a sinistra è numericamente maggiore dell'argomento a destra. >>

L'operatore binario ``<='' restituisce un valore vero se l'argomento a sinistra è numericamente minore o uguale dell'argomento a destra >

L'operatore binario ``>='' restituisce un valore vero se l'argomento a sinistra è numericamente maggiore o uguale dell'argomento a destra. = >>

L'operatore binario ``lt'' restituisce un valore vero se l'argomento a sinistra, visto come stringa, è minore dell'argomento a destra. >

L'operatore binario ``gt'' restituisce un valore vero se l'argomento a sinistra, visto come stringa, è maggiore dell'argomento a destra. >

L'operatore binario ``le'' restituisce un valore vero se l'argomento a sinistra, visto come stringa, è minore o uguale dell'argomento a destra. >

L'operatore binario ``ge'' restituisce un valore vero se l'argomento a sinistra, visto come stringa, è maggiore o uguale dell'argomento a destra. >

Operatori di uguaglianza

L'operatore binario ``=='' restituisce un valore vero se l'argomento a sinistra è numericamente uguale all'argomento a destra.

L'operatore ``!='' restituisce un valore vero se l'argomento a sinistra è numericamente non uguale all'argomento a destra.

L'operatore ``<=>'' restituisce -1, 0, o 1 a seconda che l'argomento a sinistra sia numericamente minore, uguale, o maggiore dell'argomento a destra. Se la vostra piattaforma supporta i NaNs (not-a-number) [non un numero, NdR] come valori numerici, usando questi con ``<=>'' restituisce undef. NaN non è ``<'', ``=='', ``>'', ``<='' o ``>='' a qualsiasi cosa (anche NaN), quindi questi 5 restituiscono falso. NaN != NaN restituisce un valore vero, così come NaN != qualsiasi altra cosa. Se la vostra piattaforma non supporta NaN allora NaN è solamente una stringa con valore numerico uguale a 0. >>

    perl -le '$a = "NaN"; print "NaN non supportato" if $a == $a'
    perl -le '$a = "NaN"; print "NaN supportato" if $a != $a'

L'operatore binario ``eq'' restituisce un valore vero se l'argomento a sinistra, visto come stringa, è uguale all'argomento a destra.

L'operatore binario ``ne'' restituisce un valore vero se l'argomento a sinistra, visto come stringa, non è uguale all'argomento a destra.

L'operatore binario ``cmp'' restituisce -1, 0 o 1 a seconda che l'argomento a sinistra sia, visto come stringa, minore, uguale o maggiore dell'argomento a destra.

Se è abilitato use locale, ``lt'', ``le'', ``ge'', ``gt'' e ``cmp'' usano l'ordinamento specificato dal locale corrente. Si veda anche perllocale.

And bit a bit

L'operatore binario ``&'' restituisce l'AND bit a bit dei suoi operandi. (Si vedano anche Aritmetica Intera e Operatori bit a bit su stringhe).

Va notato che ``&'' ha priorità minore degli operatori di confronto, per esempio le parentesi sono essenziali in un test come

    print "uguale\n" if ($x & 1) == 0;

Or bit a bit e Or esclusivo bit a bit

L'operatore binario ``|'' restituisce l'OR bit a bit dei suoi operandi. (Si vedano anche Aritmetica Intera e Operatori bit a bit su stringhe).

L'operatore binario ``^'' restituisce lo XOR bit a bit dei suoi operandi. (Si vedano anche Aritmetica Intera e Operatori bit a bit su stringhe).

Va notato che gli operatori ``|'' e ``^'' hanno priorità minore rispetto agli operatori di confronto, ad esempio le parentesi sono essenziali in un confronto come

    print "falso\n" if (8 | 2) != 10;

And logico in stile C

L'operatore binario ``&&'' esegue l'operazione di AND logico cortocircuitato. Ciò significa che, se l'operando a sinistra è falso, l'operando a destra non viene nemmeno valutato. Se avviene tale valutazione dell'operando, il contesto scalare o quello di lista viene propagato sulla valutazione dell'operando a destra. Esempi by dakkar:

    # il primo operando e` vero, il contesto lista e` propagato
    # al secondo operando di &&
    @a= 1 && ('abc'=~/(.)(.)(.)/)
    dopo @a==qw(a b c)

    # il primo operando e` vero, il contesto scalare e` propagato
    # al secondo operando di &&
    $a= 1 && ('abc'=~/(.)(.)(.)/)
    dopo, $a==1

    # in questo caso il primo operando e` falso (c`e` \d su un carattere)
    # quindi restituisce falso e lista vuota
    @a= ('abc'=~/(\d)(\d)(\d)/) && ('abc'=~/(.)(.)(.)/)  --> @a=('')

=head2 Or logico in stile C
X<||> X<operator, logical, or>

L'operatore binario ``||'' esegue l'operazione di OR logico cortocircuitato. Ciò vuol dire che se l'operatore a sinistra è vero, l'operatore a destra non sarà valutato. Se avviene tale valutazione dell'operando il contesto scalare o quello di lista viene propagato sulla valutazione del secondo operando.

Gli operatori || e && restituiscono l'ultimo valore valutato (diversamente dal || e il && del C, i quali restituiscono 0 o 1). Quindi, un modo ragionevolmente portabile di scoprire la propria directory home potrebbe essere:

    $home = $ENV{'HOME'} || $ENV{'LOGDIR'} ||
    getpwuid($<))[7] || die "Sei senza casa!\n";

In particolare, questo significa che non si deve utilizzare questo metodo per la selezione tra due valori non scalari (array o hash):

    @a = @b || @c;              # questo e` sbagliato
    @a = scalar(@b) || @c;      # in realta` si intendeva dire questo
    @a = @b ? @b : @c;          # questo funziona bene

Come alternative più leggibili a && e ||, quando usate perl il controllo del flusso, Perl fornisce gli operatori and e or (si veda sotto). Il comportamento del cortocircuito è identico. La precedenza di ``and'' e ``or'' è molto minore, comunque, in maniera tale che possiate utilizzarli dopo un operatore lista senza il bisogno delle parentesi:

    unlink "alpha", "beta", "gamma"
        or afferra(), next LINE;

Con gli operatori stile C questo sarebbe stato scritto così:

    unlink("alpha", "beta", "gamma")
        || (afferra(), next LINE);

Usare ``or'' per l'assegnamento è improbabile che faccia ciò che si vuole; si veda sotto.

Operatori di Intervallo

L'operatore binario ``..'' è l'operatore di intervallo, che si comporta davvero come due operatori differenti in base al contesto di utilizzazione. In contesto di lista, restituisce una lista di valori contando (uno dopo l'altro) dal valore di sinistra al valore di destra. Se il valore di sinistra è maggiore di quello di destra allora viene restituita una lista vuota. L'operatore di intervallo è utile per scrivere cicli tipo foreach (1..10) e per fare operazioni di slice sugli array. Nell'implementazione corrente, quando l'operatore di intervallo viene utilizzato come espressione nei cicli di tipo foreach, non viene creato alcun array temporaneo, ma nelle versioni più vecchie di Perl si potrebbe sprecare molta memoria quando si scrive qualcosa come questo:

    for (1 .. 1_000_000) {
        # code
    }

L'operatore di intervallo funziona anche sulle stringhe, quando viene usato l'auto-incremento magico, si veda sotto.

In contesto scalare, ``..'' restituisce un valore booleano. L'operatore è bi-stabile [ha due stati, NdT] come un flip-flop [dispositivo elettronico di memoria elementare, NdT] ed emula l'operatore virgola di sed, awk, e vari editor. Ciascun operatore ``..'' mantiente il suo stato booleano personale. Esso è falso finché il suo operando a sinistra è falso. Una volta che l'operando a sinistra diventa vero, l'operatore di intervallo rimane vero finché l'operando a destra è vero, DOPODICHÉ l'operatore di intervallo diventa falso di nuovo. Non diventa falso fino alla prossima volta in cui viene valutato l'operatore di intervallo. Esso può testare l'operando a destra e diventare falso durante la stessa valutazione in cui era diventato vero (come in awk), ma rimarrà ancora una volta vero. Se non volete che testi l'operando a destra fino alla prossima valutazione, come in sed, allora usate tre punti (``...'') invece di due. In altre valutazioni, ``...'' si comporta correttamente come fa ``..''.

L'operando a destra non viene valutato quando l'operatore si trova nello stato di falso, e l'operando a sinistra non viene valutato quando l'operatore si trova invece nello stato di vero. La precedenza è leggermente minore rispetto a quella di || e &&. Il valore restituito può essere sia una stringa vuota per lo stato di falso, oppure una sequenza di numeri (che cominciano con 1) per lo stato di vero. Il numero di sequenza viene reimpostato per ogni intervallo incontrato. Il numero di sequenza finale in un intervallo, ha aggiunta in coda la stringa ``E0'', la quale non altera il suo valore numerico, ma vi offre un qualcosa di utile per cercarla se volete escludere il punto di terminazione. Potete escludere il punto di inizio aspettando che il numero di sequenza sia maggiore di 1.

Se nemmeno l'operando di ``..'' è un'espressione costante, quell'operando è considerato vero se è uguale (==) al numero numero di riga di input corrente (la variabile $.).

Per essere pignoli, il confronto è realmente int(EXPR) == int(EXPR), ma è realmente un problema se si usa un'espressione in virgola mobile; quando implicitamente usate $. come descrito nel precedente paragrafo, il confronto tra int(EXPR) == int($.) diventa un problema quando $. è impostato ad un valore in virgola mobile e non state leggendo da un file. Inoltre, "span" .. "spat" oppure 2.18 .. 3.14 non faranno quello che vi aspettate in contesto scalare, perché ciascun operando viene valutato utilizzando la sua rappresentazione intera.

Esempi:

Come operatore scalare:

    if (101 .. 200) { print; } # stampa le seconde centinaia di righe, una abbreviazione per
                               #   if ($. == 101 .. $. == 200) ...
    next LINE if (1 .. /^$/);  # salta le righe di intestazione, una abbreviazione per
                               #   ... if ($. == 1 .. /^$/);
                               # (tipicamente in un ciclo etichettato con LINE)
    s/^/> / if (/^$/ .. eof());  # quote del testo di una email
    # fa il parsing dei messaggi mail
    while (<>) {
        $nella_intestazione =   1  .. /^$/;
        $nel_corpo   = /^$/ .. eof;
        if ($nella_intestazione) {
            # ...
        } else { # nel corpo
            # ...
        }
    } continue {
        close ARGV if eof;             # reimposta $. per ogni file
    }

Ecco un semplice esempio per illustrare le differenze tra i due operatori di intervallo:

    @linee = ("   - Pippo",
              "01 - Pluto",
              "1  - Paperino",
              "   - Topolino");
    foreach (@linee) {
        if (/0/ .. /1/) {
            print "$_\n";
        }
    }

Questo programma stamperà solo le linee contenenti ``Pluto''. Se l'operatore di intervallo viene sostituito con ..., stamperà la linea ``Paperino''.

Ed ora alcuni semplici esempi come operatore di lista:

    for (101 .. 200) { print; }         # stampa $_ 100 volte
    @pippo = @pippo[0 .. $#pippo];      # un "nop" [non far nulla, NdR] dispendioso
    @pippo = @pippo[$#pippo-4 .. $#pippo];  # effettua uno slice degli ultimi 5 elementi

L'operatore di intervallo (in contesto di lista) fa uso dell'algoritmo magico di auto-incremento nel caso in cui gli operandi siano stringhe. Potete affermare

    @alfabeto = ('A' .. 'Z');

per ottenere tutte le normali lettere dell'alfabeto Inglese, oppure

    $cifreesa = (0 .. 9, 'a' .. 'f')[$num & 15];

per ottenere una cifra esadecimale, oppure

    @z2 = ('01' .. '31');  print $z2[$giornodelmese];

per ottenere le date con degli zero iniziali. Se il valore finale specificato non è nella sequenza che viene prodotta dall'incremento magico, la sequenza arriva fino a che il valore successivo sarebbe stato più lungo del valore finale specificato.

Dato che ogni operando viene valutato in forma di intero, in contesto di lista 2.18 .. 3.14 restituirà due elementi.

    @lista = (2.18 .. 3.14); # lo stesso che @lista = (2 .. 3);

Operatore condizionale

Il ``?:'' ternario è l'operatore condizionale, proprio come in C. Funziona grossomodo come un if-then-else [se-allora-altrimenti, NdT]. Se l'argomento prima del ? è vero, restituisce l'argomento prima del :, altrimenti restituisce l'argomento dopo il :. Ad esempio:

    printf "Io ho %d can%s.\n", $n,
        ($n == 1) ? 'e' : 'i';

Il contesto scalare o di lista si propaga verso il secondo o terzo parametro (quello dei due che viene selezionato).

    $a = $ok ? $b : $c;  # restituisce uno scalare
    @a = $ok ? @b : @c;  # resistuisce un array
    $a = $ok ? @b : @c;  # oops, restituisce il numero di elementi!

È possibile utilizzare l'operatore in un'assegnazione se entrambi gli argomenti (il secondo e il terzo) sono lvalue validi (ossia, possono essere utilizzati in un'assegnazione):

    ($a_o_b ? $a : $b) = $c;

Dal momento che l'operatore produce un risultato assegnabile, usarlo in una assegnazione senza le parentesi può essere fonte di guai. Ad esempio, questo:

    $a % 2 ? $a += 10 : $a += 2

Vuol dire in realtà questo:

    (($a % 2) ? ($a += 10) : $a) += 2

Invece che questo:

    ($a % 2) ? ($a += 10) : ($a += 2)

Ciò dovrebbe probabilmente essere scritto più semplicemente così:

    $a += ($a % 2) ? 10 : 2;

Operatori di Assegnamento >> >= >>>

``='' è l'usuale operatore di assegnamento.

Gli operatori di assegnamento funzionano come in C. Cioè,

    $a += 2;

equivale a

    $a = $a + 2;

pur senza duplicare gli effetti collaterali che la dereferenziazione dell'lvalue potrebbe innescare, come nel caso di variabili sottoposte a tie(). Gli altri operatori di assegnamento funzionano in maniera simile. I seguenti operatori sono validi:

    **=    +=    *=    &=    <<=    &&=
           -=    /=    |=    >>=    ||=
           .=    %=    ^=
                 x=

Sebbene questi siano raggruppati per famiglia, tutti hanno la precedenza dell'assegnamento.

Diversamente dal C, l'operatore di assegnamento scalare produce un lvalue valido. Modificare un assegnamento è equivalente a fare un assegnamento e poi modificare la variabile che si era assegnata. Questo è utile per modificare una copia di qualcosa, come questo:

    ($temp = $globale) =~ tr [A-Z] [a-z];

Così come,

    ($a += 2) *= 3;

è equivalente a

    $a += 2;
    $a *= 3;

Analogamente, l'assegnamento di una lista in contesto di lista produce la lista degli lvalue assegnati, e l'assegnamento di una lista in contesto scalare restituisce il numero di elementi prodotti dall'espressione sul lato destro dell'assegnamento.

Operatore Virgola

``,'' è l'operatore binario virgola. In contesto scalare esso valuta il suo argomento a sinistra, ne scarta il valore, poi valuta il suo argomento a destra e restituisce tale valore.

In contesto di lista, è il separatore degli argomenti di una lista, e inserisce entrambi i suoi argomenti in una lista.

L'operatore => è un sinonimo dell'operatore virgola, ma forza qualsiasi parola (formata interamente da caratteri) alla sua sinistra ad essere interpretata come una stringa (dalla versione 5.001). Questo include parole che altrimenti potrebbero essere essere considerate come una costante o una chiamata di funzione.

    use constant PIPPO => "qualcosa";
    my %h = ( PIPPO => 23 );

è equivalente a:

    my %h = ("PIPPO", 23);

NON è:

    my %h = ("qualcosa", 23);

Se l'argomento sulla sinistra non è una parola, esso viene prima interpretato come un'espressione, e poi viene usato il suo valore come stringa.

L'operatore => è utile nel documentare la corrispondenza tra chiavi e valori negli hash, ed altri elementi accoppiati nelle liste.

    %hash = ( $chiave => $valore );
    login( $username => $password );

Operatori di Lista (associatività a destra)

Sul lato destro di un operatore di lista, si ha una precedenza molto bassa, in modo tale che l'operatore controlli tutte le espressioni separate da virgola che vi trova. Gli unici operatori con precedenza più bassa sono gli operatori logici ``and'', ``or'', e ``not'', i quali possono essere usati per valutare chiamate a operatori di lista senza il bisogno di ulteriori parentesi:

    open HANDLE, "nomefile"
        or die "Non posso aprire: $!\n";

Si veda anche la discussione sugli operatori di lista in Termini e Operatori di Lista (associatività a sinistra).

Not logico

L'operatore unario ``not'' restituisce la negazione logica dell'espressione alla sua destra.

And logico

L'operatore binario ``and'' restituisce la congiunzione logica delle due espressioni che lo contornano. È equivalente a && eccetto che per la precedenza molto bassa. Questo significa che esso cortocircuita: cioè l'espressione sulla destra viene valutata solo se l'espressione a sinistra è vera.

Or Logico e Or Esclusivo

L'operatore binario ``or'' restituisce la disgiunzione logica tra le due espressioni che lo contornano. È equivalente a || eccetto che per la precedenza molto bassa. Questo lo rende molto utile per il controllo di flusso

    print FH $dati      or die "Non posso scrivere su FH: $!";

Questo significa che esso cortocircuita: cioè l'espressione a destra viene valutata solamente se l'espressione a sinistra è falsa. A causa della sua precedenza, dovreste probabilmente evitare di utilizzarlo negli assegnamenti, solo per il controllo di flusso.

    $a = $b or $c;      # bug: questo e` sbagliato
    ($a = $b) or $c;    # vuol dire proprio quel che si intende
    $a = $b || $c;      # va meglio scritto in questo modo

Tuttavia, quando si trova in un assegnamento in contesto di lista e si sta cercando di utilizzare ``||'' per il controllo di flusso, probabilmente si avrà bisogno di ``or'' in modo che l'assegnamento assuma una precedenza più alta.

    @info = stat($file) || die;     # oops, stat con significato scalare
    @info = stat($file) or die;     # meglio, ora @info prende cio` che gli spetta

Anche stavolta, si possono sempre usare le parentesi.

    ( @info = stat($file) ) || die; # NdT

L'operatore binario ``xor'' restituisce l'OR-esclusivo delle due espressioni che lo circondano. Esso non può ovviamente cortocircuitare.

Gli Opearatori del C mancanti in Perl

Ecco le cose ha il C ma che non ha il Perl:

& unario
Operatore di indirizzo. (Ma date un'occhiata all'operatore ``\'' per ottenere un riferimento).

  • unario
    Operatore di dereferenziazione. (I prefessi di dereferenziazione in Perl sono tipati: $, @, %, e &).

    (TYPE)
    Operatore di type-casting [conversione di tipo, NdR]

  • Operatori per il quote ed equivalenti >>

    Mentre di solito si pensa ai quote come a dei valori letterali, in Perl funzionano come operatori, fornendo varie tipologie di interpolazione e capacità di pattern matching. Per queste modalità di funzionamento, Perl fornisce i consueti caratteri di quote, ma fornisce anche una strada per scegliere carattere di quote per ciascuno di essi. Nella seguente tabella, un {} rappresenta una coppia di delimitatori da scegliere.

        Consueto  Generico       Significato    Interpola
           ''       q{}          Letterale        no
           ""       qq{}          Letterale       si`
           ``       qx{}           Comando        si`*
                    qw{}        Lista di parole   no
           //       m{}         Pattern match     si`*
                    qr{}           Pattern        si`*
                    s{}{}       Sostituzione      si`*
                    tr{}{}     Traslitterazione   no (ma si veda sotto)
           <<EOF                   here-doc       si`*
            * a meno che il delimitatore non sia ''.

    I delimitatori senza graffe usano lo stesso carattere a prua e a poppa, ma i quattro tipi di parentesi (tonde, angolari, quadrate, graffe) saranno tutti annidati, ciò significa che

        q{pippo{pluto}paperino}

    è lo stesso che

        'pippo{pluto}paperino'

    Va notato, comunque, che questo non sempre funziona nel quotare codice Perl:

        $s = q{ if($a eq "}") ... }; # SBAGLIATO

    è un errore di sintassi. Il modulo Text::Balanced (scaricabile da CPAN, e con Perl 5.8 entrato a far parte della distribuzione standard) è capace di farlo correttamente.

    Ci può essere uno spazio tra l'operatore e i caratteri di quoting, eccetto che quando # è stato usato come carattere di quoting. Di q#pippo# viene effettuato il parsing come stringa pippo, mentre q #pippo# è l'operatore q seguito da un commento. Il suo argomento sarà preso dalla linea che segue. Questo vi permette di scrivere:

        s {pippo}  # Rimpiazza pippo
          {pluto}  # con pluto.

    Le seguenti sequenze di escape sono disponibili in costrutti che effettuano interpolazioni e nelle traslitterazioni.

        \t          tab                             (HT, TAB)
        \n          newline                         (NL)
        \r          return                          (CR)
        \f          form feed                       (FF)
        \b          backspace                       (BS)
        \a          alarm (bell)                    (BEL)
        \e          escape                          (ESC)
        \033        carattere ottale                (ESC)
        \x1b        carattere esadecimale           (ESC)
        \x{263a}    carattere esadec. esteso        (SMILEY)
        \c[         carattere di controllo          (ESC)
        \N{nome}    carattere Unicode nominale

    NOTA: Diversamente dal C ed altri linguaggi, Perl non ha la sequenza di escape \v per il tab verticale (VT - ASCII 11).

    Le seguenti sequenze di escape sono disponibili in costrutti che interpolano, ma non nelle traslitterazioni.

        \l      rende il carattere successivo minuscolo
        \u      rende il carattere successivo maiuscolo
        \L      rende minuscolo fino a \E
        \U      rende maiuscolo fino \E
        \E      termina la modifica del case
        \Q      quota i metacaratteri fino a \E

    Se state usando use locale, la mappatura di maiuscole/minuscole usata da \l, \L, \u e \U viene presa dalle impostazioni linguistiche correnti. Si veda perllocale. Se è stato usato Unicode (per esempio, \N{} o caratteri esadecimali più grandi di 0x100), la mappatura di maiuscole/minuscole usata da \l, \L, \u e \U segue la definizione dello standard Unicode. Per la documentazione di \N{name}, si veda charnames.

    Tutti i sistemi utilizzano "\n" per rappresentare un terminatore di linea, chiamato ``newline'' [letteralmente ``nuova linea'', NdT]. Non esiste qualcosa come un invariante, un carattere fisico del newline. Esso rappresenta solo un'illusione che il sistema operativo, i driver, le librerie C, e il Perl cospirano a preservare! Non tutti i sistemi leggono "\r" come ASCII CR e "\n" come ASCII LF. Per esempio, su un Mac, questi sono invertiti, e su sistemi senza il terminatore di linea, stampare "\n" potrebbe non emettere dati reali. In generale, usate "\n" quando intendete un ``newline'' per il vostro sistema, ma usate un ASCII letterale quando avete bisogno di un carattere esatto. Per esempio, la maggior parte dei protocolli di networking si aspetta e preferisce un CR+LF ("\015\012" o "\cM\cJ") per i terminatori di linea, e sebbene essi spesso accettino anche solo "\012", essi raramente tollerano solo "\015". Se prendete l'abitudine di usare "\n" per il networking, un giorno o l'altro potreste prendervi una scottatura.

    Per costrutti che interpolano, le variabili che iniziano con ``$'' o ``@'' verranno interpolate. Variabili come $a[3] oppure $href->{key}[0] verranno anch'esse interpolate, così come gli slice [fette, NdT] di array e hash. Ma non le chiamate ad un metodo come $oggetto->metodo.

    Interpolare un array o uno slice, interpola gli elementi nell'ordine, separati dal valore di $"; il che è equivalente ad interpolare join $", @array. Gli array ``Punctuation'' [array il cui nome è costituito da segni di punteggiatura, NdT] come @+ sono interpolati solamente se il nome è racchiuso tra parentesi @{+}.

    Non è possibile includere un letterale come $ o @ all'interno di una sequenza \Q. Un $ o @ senza escape [non preceduti da \, NdT] interpolano la variabile corrispondente, mentre facendo precedere la sequenza da un \ causerà l'inserimento della stringa letterale \$. Dovrete scrivere qualcosa come m/\Quser\E\@\Qhost/.

    I pattern sono soggetti ad un addizionale livello di interpretazione come le espressioni regolari. Questo viene fatto in un secondo passo, dopo che le variabili sono state interpolate, così che l'espressione regolare possa essere incorporata nel pattern, dalle variabili. Se non è questo che volete, usate \Q per interpolare una variabile in maniera letterale.

    A parte il comportamento sopra descritto, Perl non espande più livelli di interpolazione. In particolare, contrariamente alle aspettative dei programmatori shell, il back-quote [l'uso dei due backtick, ovvero gli apici inversi: ` qualcosa `, NdR] NON interpola all'interno di un doppio quote [l'uso delle virgolette doppie: `` qualcosa '', NdR], né tantomeno i quote singoli [virgolette ', NdR] impediscono la valutazione delle variabili se utilizzate all'interno di un doppio quote.

    Operatori Quote-Like per Espressioni Regolari

    Ecco gli operatori a-la quote che si applicano al pattern matching e ad attività correlate.

    ?PATTERN?
    Questo è come la ricerca con /pattern/, eccetto che trova una corrispondenza solo per una volta fra chiamate all'operatore reset(). Per esempio, rappresenta una utile ottimizzazione quando si vuole visualizzare solo la prima occorrenza di qualcosa in ogni file di un insieme di file. Con reset() vengono reimpostati solo i pattern ?? locali al package corrente.
        while (<>) {
            if (?^$?) {
                                    # linea vuota tra intestazione e corpo
            }
        } continue {
            reset if eof;           # pulisce lo stato di ?? per il prossimo file
        }

    Questo utilizzo è vagamente deprecato, il che significa che potrebbe forse essere rimosso in qualche versione di Perl nel lontano futuro, forse da qualche parte intorno all'anno 2168.

    m/PATTERN/cgimosx
    /PATTERN/cgimosx
    Cerca una stringa per un pattern match, e in un contesto scalare restituisce vero se la corrispondenza viene trovata, falso altrimenti. Se non viene specificata alcuna stringa attraverso l'operatore =~ o !~, la ricerca della stringa avviene in $_. (La stringa specificata con =~ non deve essere un lvalue [valore a sinistra di un'espressione, NdT] -- potrebbe essere il risultato della valutazione di un'espressione, ma va ricordato che =~ ha una precedenza molto alta). Si veda anche perlre. Si veda perllocale per ulteriori considerazioni da applicare quando è in uso use locale.

    Le opzioni sono:

        c   Non reimposta la posizione di ricerca in seguito ad un match fallito quando si sta utilizzando /g .
        g   Fa un match globale, cioe` trova tutte le occorrenze.
        i   Esegue un pattern match senza preoccuparsi di maiuscole o minuscole.
        m   Tratta le stringhe come linee multiple.
        o   Compila il pattern solo una volta.
        s   Tratta la stringa come una singola linea.
        x   Usa le espressioni regolari estese.

    Se il delimitatore è ``/'', allora la m iniziale è opzionale. Con m potete usare una coppia di caratteri non alfanumerici, che non siano spazi, come delimitatori. Questo è particolarmente utile quando si sta eseguendo il match di percorsi di nomi che contengono ``/'', per evitare la LTS (leaning toothpick syndrome) [sindrome dello stuzzicadenti inclinato, NdT]. Se il delimitatore è ``?'', allora si applica la regola del match-solo-per-una-volta di ?PATTERN?. Se il delimitatore è ``''', non viene effettuata l'interpolazione sul PATTERN.

    PATTERN può contenere delle variabili, le quali saranno interpolate (e il pattern ricompilato) ogni volta che viene valutato il pattern di ricerca, tranne quando il delimitatore è un quote singolo [ ' , NdR]. (Va notato che $(, $), e $| non sono interpolati perché assomigliano a dei test di fine stringa). Se volete che tali pattern siano compilati solo una volta, aggiungete un /o dopo il delimitatore finale. Questo evita costose ricompilazioni a tempo di esecuzione, ed è utile quando il valore che state interpolando non cambierà durante il tempo di vita del programma. Comunque, menzionare /o costituisce una promessa a non cambiare le variabili nel pattern. Se le cambiate, Perl non ve lo notificherà. Si veda anche qr/STRINGA/imosx.

    Se PATTERN restituisce la stringa vuota, verrà utilizzata l'ultima espressione regolare valutata con successo. In questo caso, sul pattern vuoto avranno effetto solo i flag g e c - gli altri flag vengono presi dal pattern originale. Se in precedenza non è avvenuto alcun match, ciò agirà (silenziosamente) come un vero e proprio pattern vuoto (che farà sempre match).

    Se non viene utilizzata l'opzione /g, m// in contesto di lista restituisce una lista che consiste di sottoespressioni che hanno fatto match con le parentesi nel pattern, cioè, ($1, $2, $3...). (Va notato che qui $1 ecc. vengono anche impostati, e che ciò è diverso dal comportamento che si aveva in Perl 4). Quando non ci sono parentesi nel pattern, il valore restituito per indicare il successo è la lista (1). Con o senza parentesi, a seguito di un insuccesso viene restituita una lista vuota.

    Esempi:

        open(TTY, '/dev/tty');
        <TTY> =~ /^y/i && pippo();  # esegue pippo se lo si desidera
        if (/Versione: *([0-9.]*)/) { $versione = $1; }
        next if m#^/usr/spool/uucp#;
        # il grep dei poveri
        $arg = shift;
        while (<>) {
            print if /$arg/o;   # compila solo una volta
        }
        if (($F1, $F2, $Ecc) = ($pippo =~ /^(\S+)\s+(\S+)\s*(.*)/))

    L'ultimo esempio divide $pippo nelle prime due parole e in ciò che rimane della linea, ed assegna questi tre campi a $F1, $F2, ed $Ecc. La condizione è vera se qualsiasi delle variabili viene assegnata, cioè, se al pattern è corrisposto un match.

    Il modificatore /g specifica un pattern matching globale -- cioè, fa match più volte possibile all'interno della stringa. Come si comporta dipende dal contesto. In contesto di lista, restituisce una lista delle sottostringhe a cui è corrisposto un match, come se ci fossero parentesi intorno all'intero pattern.

    In contesto scalare, ciascuna esecuzione di m//g trova il match successivo, restituendo vero se ha effettuato il match, e falso se non ci sono ulteriori match. La posizione dopo l'ultimo match può esser letta o impostata utilizzando la funzione pos(); si veda perlfunc/pos. Un match che fallisce, di norma reimposta la posizione di ricerca all'inizio della stringa, ma lo si può evitare con l'aggiunta del modificatore /c (ad es. m//gc). Se la stringa alla quale si applica il match viene modificata, la posizione di ricerca sarà reimpostata.

    Potete mescolare il match m//g con m/\G.../g, dove \G è un'asserzione zero-width [di ampiezza zero, NdT] che effettua il match all'esatta posizione dove l'eventuale precedente m//g si era interrotto. Senza il moficiatore /g, l'asserzione \G si ancora ancora a pos(), ma il match viene ovviamente tentato solo una volta. Usare \G senza /g su una stringa sulla quale non è stato applicato un match di tipo /g, equivale ad un'asserzione \A che effettua il match dell'inzio della stringa. Va notato anche che, al momento, \G è adeguatamente supportato solo quando è ancorato all'inzio del pattern.

    Esempi:

        # contesto di lista
        ($uno,$cinque,$quindici) = (`uptime` =~ /(\d+\.\d+)/g);
        # contesto scalare
        $/ = "";
        while (defined($capoverso = <>)) {
            while ($capoverso =~ /[a-z]['")]*[.!?]+['")]*\s/g) {
                    $frasi++;
            }
        }
        print "$frasi\n";
        # utilizzo di m//gc con \G
        $_ = "ppooqppqq";
        while ($i++ < 2) {
            print "1: '";
            print $1 while /(o)/gc; print "', pos=", pos, "\n";
            print "2: '";
            print $1 if /\G(q)/gc;  print "', pos=", pos, "\n";
            print "3: '";
            print $1 while /(p)/gc; print "', pos=", pos, "\n";
        }
        print "Finale: '$1', pos=",pos,"\n" if /\G(.)/;

    L'ultimo esempio dovrebbe stampare:

        1: 'oo', pos=4
        2: 'q', pos=5
        3: 'pp', pos=7
        1: '', pos=7
        2: 'q', pos=8
        3: '', pos=8
        Finale: 'q', pos=8

    Si noti che l'ultimo match ha effettuato il match di q invece di p, la stessa cosa che avrebbe fatto un match senza l'ancora \G. Si noti anche che l'ultimo match non ha aggiornato pos -- pos viene aggiornato solamente su un match con /g. Se il match finale ha davvero effettuato il match di p, ci sarebbe da scommettere che si sta utillizzando un Perl più vecchio (pre-5.6.0).

    Un idioma utile per gli scanner sul genere di lex, è /\G.../gc. È possibile combinare diverse espressioni regolari come questa per elaborare una stringa pezzo per pezzo, eseguendo diverse azioni a seconda dell'espressione regolare corrispondente. Ogni espressione regolare cerca di effettuare il match da dove ha terminato la precedente.

     $_ = <<'EOL';
          $url = new URI::URL "http://www/";;   die if $url eq "xXx";
     EOL
     LOOP:
        {
          print(" cifre"),              redo LOOP if /\G\d+\b[,.;]?\s*/gc;
          print(" minuscolo"),          redo LOOP if /\G[a-z]+\b[,.;]?\s*/gc;
          print(" MAISUCOLO"),          redo LOOP if /\G[A-Z]+\b[,.;]?\s*/gc;
          print(" Primo carattere maiuscolo"),  redo LOOP if /\G[A-Z][a-z]+\b[,.;]?\s*/gc;
          print(" MiStO"),              redo LOOP if /\G[A-Za-z]+\b[,.;]?\s*/gc;
          print(" alfanumerico"),           redo LOOP if /\G[A-Za-z0-9]+\b[,.;]?\s*/gc;
          print(" rumore di linea"),        redo LOOP if /\G[^A-Za-z0-9]+/gc;
          print ". E` tutto!\n";
        }

    Ecco qui l'output (diviso su diverse linee):

     rumore di linea minuscolo rumore di linea minuscolo MAISUCOLO rumore di linea
     MAISUCOLO rumore di linea minuscolo rumore di linea minuscolo rumore di linea
     minuscolo minuscolo rumore di linea minuscolo minuscolo rumore di linea
     MiStO rumore di linea. E` tutto!

    q/STRINGA/
    'STRINGA'
    Una stringa letterale, con quote singolo. Un backslash rappresenta un backslash se non è seguito da un delimitatore o da un altro backslash, in tal caso il delimitatore o backslash viene interpolato.
        $pippo = q!Ho detto, "Tu dici, 'Lei lo dice.'"!;
        $pluto = q('Questo e`.');
        $paperino = '\n';        # una stringa di due caratteri

    qq/STRINGA/

    ``STRINGA''
    Un doppio quote, stringa interpolata.
        $_ .= qq
         (*** La riga precedente contiene l'indecente parola "$1".\n)
            if /\b(tcl|java|python)\b/i;      # :-)
        $paperino = "\n";       # una stringa di un carattere

    qr/STRINGA/imosx
    Questo operatore quota (e possibilmente compila) la sua STRINGA come una espressione regolare. STRINGA viene interpolata allo stesso modo di PATTERN in m/PATTERN/. Se come delimitatore viene usato ``''', l'interpolazione non viene fatta. Restituisce un valore Perl che può essere usato al posto della corrispondente espressione /STRINGA/imosx.

    Per esempio,

        $rex = qr/mia.STRINGA/is;
        s/$rex/pippo/;

    è equivalente a

        s/mia.STRINGA/pippo/is;

    Il risultato può esser utilizzato come un sotto-pattern in un match:

        $re = qr/$pattern/;
        $stringa =~ /pippo${re}pluto/;      # puo` esser interpolato in altri pattern
        $stringa =~ $re;                    # oppure usato da solo
        $stringa =~ /$re/;                  # o in questo modo

    Dato che Perl può compilare il pattern al momento dell'esecuzione dell'operatore qr(), in alcune situazioni utilizzare qr() potrebbe portare a dei vantaggi in termini di velocità, specialmente se il risultato di qr() viene utilizzato da solo:

        sub match {
            my $patterns = shift;
                my @compilato = map qr/$_/i, @$patterns;
                grep {
                    my $successo = 0;
                    foreach my $pat (@compilato) {
                            $successo = 1, last if /$pat/;
                    }
                    $successo;
                } @_;
        }

    La precompilazione del pattern in una rappresentazione interna al momento dell'esecuzione di qr() evita il bisogno di ricompilare il pattern ogni volta che si tenta un match /$pat/. (Perl ha molte altre ottimizzazioni interne, ma non sarebbero entrate in gioco nell'esempio predecendete se non avessimo usato l'operatore qr()).

    Le opzioni sono:

        i   Effettua un pattern matching senza badare a minuscole/maiuscole.
        m   Tratta la stringa come fosse su piu` linee.
        o   Compila il pattern una volta sola.
        s   Tratta la stringa come fosse una singola linea.
        x   Utilizza le espressioni regolari estese.

    Si veda perlre per delle informazioni aggiuntive sulla sintassi valida per STRINGA, e per uno sguardo dettagliato alla semantica delle espressioni regolari.

    qx/STRINGA/
    `STRINGA`
    Una stringa che viene (forse) interpolata e poi eseguita come un comando di sistema con /bin/sh o equivalente. Sarà rispettato l'utilizzo dei caratteri jolly della shell [le wildcard * ? ecc, NdR], pipe e redirezioni. L'output raccolto viene restituito; lo standard error no. In contesto scalare, se il comando fallisce viene restituita come singola stringa (potenzialmente multilinea), oppure undef. In contesto di lista, se il comando fallisce restituisce una lista di linee (o comunque in base a come è stato definito $/ o $INPUT_RECORD_SEPARATOR), o una lista vuota .

    Dato che il backtick non influisce sullo standard error, se interessa risolvere tale questione va usata la sintassi di shell per il descrittore di file (supponendo che la shell la supporti). Per catturare assieme lo STDERR e STDOUT di un comando:

        $output = `cmd 2>&1`;

    Per catturare lo STDOUT ma scartare il suo STDERR:

        $output = `cmd 2>/dev/null`;

    Per catturare lo STDERR di un comando ma scartare il suo STDOUT (l'ordine qui è importante):

        $output = `cmd 2>&1 1>/dev/null`;

    Per scambiare lo STDOUT e lo STDERR di un comando al fine di catturare lo STDERR ma lasciare che lo STDOUT termini nel vecchio STDERR:

        $output = `cmd 3>&1 1>&2 2>&3 3>&-`;

    Per leggere separatamente sia lo STDOUT che lo STDERR di un comando, è più facile redirezionarli separatamente a dei file, e poi leggere da questi file quando il programma è terminato:

        system("programma argomenti 1>programma.stdout 2>programma.stderr");

    Utilizzare un quote singolo come delimitatore protegge il comando dall'interpolazione a doppio quote di Perl, passandolo invece in una shell:

        $perl_info  = qx(ps $$);            # $$
        $shell_info = qx'ps $$';            # che e` il $$ della nuova shell

    Come quella stringa venga valutata è un affare che riguarda l'interprete del vostro sistema. Sulla maggior parte delle piattaforme, dovrete proteggere i metacaratteri della shell se volete che vengano trattati in maniera letterale. Questo in pratica è difficile da ottenere dato che non è chiaro in che modo si debba fare l'escape di tali caratteri. Si veda perlsec per un esempio pulito e sicuro di fork() ed exec() manuali per emulare in sicurezza il backtick.

    Su alcune piattaforme (specialmente quelle tipo DOS), la shell potrebbe non esser capace di trattare con comandi multi linea, quindi inserire dei newline nella stringa potrebbe non darvi quello che vi aspettate. Se la vostra shell lo supporta potete valutare comandi multipli in una linea singola separandoli con il carattere separatore di comando (ad es. ; sulla maggior parte delle shell Unix; & sulla shell cmd di Windows NT).

    A partire dalla v5.6.0, Perl cercerà di terminare le operazioni di I/O in corso di tutti i file aperti prima di iniziare il processo figlio, ma questo potrebbe non essere supportato su alcune piattaforme (si veda perlport). Per esserne sicuri, potreste aver bisogno di impostare $| ($AUTOFLUSH con il modulo English) o chiamare il metodo autoslush() di IO::Handle su ogni handle aperto.

    Fate attenzione al fatto che alcuni comandi di shell potrebbero porre delle restrizioni sulla lunghezza della linea di comando. Dovete assicurarvi che le vostre stringhe non eccedano questo limite dopo le necessarie interpolazioni. Per ulteriori dettagli riguardo al vostro ambiente si vedano le note di rilascio relative alla specifica piattaforma utilizzata.

    Usare questo operatore può portare a programmi il cui porting [migrazione tra diversi ambienti, NdR] è difficile, dato che i comandi di shell chiamati variano tra i vari sistemi, e potrebbero di fatto non essere affatto presenti. Come esempio, il comando type nelle shell POSIX è molto differente dal comando type del DOS. Ciò non significa che dovreste uscire dal vostro modo di operare per aggirare i backtick quando sono la strada giusta per ottenere il risultato. Perl fu fatto per essere un linguaggio ``glue'' [collante, NdT], e una delle cose che Perl incolla assieme sono i comandi. Dovete solo capire cova volete ottenere.

    Per ulteriori discussioni si veda Operatori di I/O.

    qw/STRINGA/
    Valuta una lista delle parole estratta dalla STRINGA, utilizzando uno spazio incorporato come delimitatore di parole. Può essere grossomodo inteso come equivalente a:
        split(' ', q/STRINGA/);

    la differenza sta nel fatto che esso genera una vera lista a tempo di compilazione, e in contesto scalare restituisce l'ultimo elemento della lista. Quindi questa espressione:

        qw( pippo pluto paperino )

    è semanticamente equivalente alla lista:

        'pippo', 'pluto', 'paperino'

    Alcuni esempi che si osservano di frequente:

        use POSIX qw( setlocale localeconv )
        @EXPORT = qw( pippo pluto paperino );

    Un errore comune è cercare di separare le parole con una virgola o mettere dei commenti in una stringa multi linea qw. Per questa ragione, la direttiva use warnings e il parametro -w (cioè, la variabile $^W) produce degli avvertimenti se la STRINGA contiene ``,'' o il carattere ``#''.

    s/PATTERN/SOSTITUZIONE/egimosx
    Cerca una stringa in base ad un pattern, e se la trova, sostituisce quel pattern con il testo di sostituzione e restituisce il numero di sostituzioni fatte. Altrimenti restituisce falso (in particolare, la stringa vuota).

    Se non viene specificata alcuna stringa tramite l'operatore =~ o !~, la ricerca e la modifica viene effettuata sulla variabile $_. (La stringa specificata con =~ deve essere una variabile scalare, un elemento di un array, un elemento di un hash, o l'assegnamento ad uno di questi, cioè, un lvalue).

    Se il delimitatore scelto è un quote singolo, non viene fatta interpolazione né su PATTERN né su SOSTITUZIONE. In caso contrario, se il PATTERN contiene un $ che assomiglia ad una variabile anziché al test di fine stringa, la variabile sarà interpolata nel pattern a tempo di esecuzione. Se volete che il pattern venga compilato solo la prima volta che la variabile viene interpolata, usate l'opzione /o. Se il pattern valuta una stringa vuota, verrà utilizzata l'ultima espressione regolare eseguita con successo. Per ulteriori spiegazioni su questo argomento si veda perlre. Per discussioni su considerazioni aggiuntive che si applicano quando è in uso use locale, si veda perllocale.

    Le opzioni sono:

        e   Valuta il lato destro di un'espressione.
        g   Rimpiazza globalmente, cioe`, tutte le occorrenze.
        i   Esegue un pattern matching senza badare a minuscole/maiuscole.
        m   Tratta la stringa come fosse su linee multiple.
        o   Compila il pattern solo una volta.
        s   Tratta la stringa come fosse una singola linea.
        x   Usa espressioni regolari estese.

    Qualsiasi delimitatore non-alfanumerico, o che non sia uno spazio, potrebbe rimpiazzare gli slash. Se viene utilizzato un singolo quote, non viene fatta un'interpretazione sulla stringa di sostituzione (ad ogni modo il modificatore /e sovrascrive questo comportamento). Diversamente da Perl 4, Perl 5 tratta i backtick come dei normali delimitatori; il testo di sostituzione non viene valutato come un comando. Se il PATTERN è delimitato da quote con parentesi, la SOSTITUZIONE ha la sua personale coppia di quote, che potrebbe o meno essere una coppia di parentesi, ad esempio, s(pippo)(pluto) oppure s<pippo>/pluto/. Un /e farà sì che la porzione di sostituzione venga trattata come una vera e propria espressione Perl e valutata immediatamente. Ad ogni modo, la sintassi viene controllata a tempo di compilazione. Un secondo modificatore e causerà un eval sulla porzione di sostituzione prima di essere eseguita come espressione Perl.

    Esempi:

        s/\bverdi\b/malva/g;    # non cambia le [piante, NdR] sempreverdi
        $path =~ s|/usr/bin|/usr/local/bin|;
        s/Login: $pippo/Login: $pluto/; # pattern a tempo di esecuzione
        ($pippo = $pluto) =~ s/questo/quello/;  # prima copia, poi cambia
        $contatore = ($paragrafo =~ s/Mister\b/Mr./g);  # conta le sostituzioni effettuate
        $_ = 'abc123xyz';
        s/\d+/$&*2/e;               # produce 'abc246xyz'
        s/\d+/sprintf("%5d",$&)/e;  # produce 'abc  246xyz'
        s/\w/$& x 2/eg;             # produce 'aabbcc  224466xxyyzz'
        s/%(.)/$percentuale{$1}/g;  # cambia la percentuale di escape; niente /e
        s/%(.)/$percentuale{$1} || $&/ge;  # ora un'espressione, dunque /e
        s/^=(\w+)/&pod($1)/ge;      # utilizza una chiamata di funzione
        # espande le variabili in $_, ma solo dinamicamente, usando
        # la dereferenziazione simbolica
        s/\$(\w+)/${$1}/g;
        # Aggiunge uno al valore di ogni numero della stringa
        s/(\d+)/1 + $1/eg;
        # Espande ogni variabile scalare
        # (inclusi i lessicali) in $_ : Prima $1 viene interpolato
        # nel nome della variabile, e poi valutato
        s/(\$\w+)/$1/eeg;
        # Cancella i commenti C (la maggior parte)
        $programma =~ s {
            /\*     # Effettua il match del delimitatore iniziale.
            .*?     # Effettua il match del minimo numero di caratteri.
            \*/     # Effettua il match del delimitatore piu` prossimo.
        } []gsx;
        s/^\s*(.*?)\s*$/$1/;    # elimina gli spazi vuoti in $_, in maniera computazionalmente dispendiosa
        for ($variabile) {      # elimina gli spazi vuoti in $_, in maniera computazionalmente conveniente
            s/^\s+//;
            s/\s+$//;
        }
        s/([^ ]*) *([^ ]*)/$2 $1/;  # inverte i primi due campi

    Va notato l'utilizzo di $ invece di \ nell'ultimo esempio. Diversamente da sed, si usa \cifra solamente nella parte sinistra. Altrove è $<cifra>.

    A volte, non si può usare un solo /g per ottenere tutti i cambi che si possono desiderare. Ecco due esempi comuni:

        # mette le virgole nei posti giusti in un numero intero 
        1 while s/(\d)(\d\d\d)(?!\d)/$1,$2/g;
        # espande i tab ad una spaziatura di 8 colonne
        1 while s/\t+/' ' x (length($&)*8 - length($`)%8)/e;

    tr/LISTADIRICERCA/SOSTITUZIONE/cds
    y/LISTADIRICERCA/LISTADISOSTITUZIONE/cds Traslittera tutte le occorrenze dei caratteri trovati nella lista di ricerca con i corrispondenti caratteri nella lista di sostituzione. Restituisce il numero di caratteri sostituiti o cancellati. Se non si specifica una stringa attraverso l'operatore =~ o !~, allora verrà  traslitterata la stringa $_. (La stringa specificata con =~ deve essere una variabile scalare, un elemento di un array, di un hash, o un assegnamento ad uno di questi, cioè, un lvalue).
    Un insieme di caratteri può essere specificato tramite un hyphen [trattino - , NdT], quindi tr/A-J/0-9/ effettua la stessa sostituzione di tr/ACEGIBDFHJ/0246813579/. Per i devoti di sed, è possibile usare y come sinonimo di tr. Se la LISTADIRICERCA è delimitata da quote con parentesi, la LISTADISOSTITUZIONE avrà la sua propria coppia di quote, che potrebbe o meno essere delle parentesi, ovvero tr[A-Z][a-z] o tr(+\-*/)/ABCD/.

    Va notato che tr non crea classi di caratteri di espressioni regolari come fanno \d o [:lower:]. L'operatore tr non è equivalente all'utility tr(1). Se si desidera effettuare il mapping tra stringhe maiuscole/minuscole, si vedano perlfunc/lc e perlfunc/uc, ed in generale si consideri l'utilizzo dell'operatore s se si ha bisogno delle espressioni regolari.

    Va notato anche che l'idea di un'intera gamma di caratteri è ben lontana dall'esser portabile tra i vari set di caratteri - ed anche all'interno degli stessi, potrebbe portare a dei risultati che non vi aspettavate. Un sano principio È quello di utilizzare degli intervalli di caratteri che iniziano e finiscono alfabeticamemente con lo stesso case (minuscolo: a-e, maiuscolo: A-E), oppure cifre (0-4). Tutto il resto è poco sicuro. Nel dubbio, va precisato interamente tutto il set di caratteri.

    Opzioni:

        c   Inverte la LISTADIRICERCA.
        d   Cancella i caratteri trovati ma non sostituiti.
        s   Riduce i caratteri sostituiti duplicati.

    Se si specifica il modificatore /c, il set di caratteri della LISTADIRICERCA viene invertito. Se viene specificato il modificatore /d, viene cancellato qualsiasi carattere specificato nella LISTADIRICERCA non trovato nella LISTADISOSTITUZIONE. (Va notato che questo è leggermente più flessibile rispetto al comportamento di alcuni programmi tr, i quali eliminano qualsiasi cosa essi trovino nella LISTADIRICERCA). Se viene specificato il modificatore /s, le sequenze di caratteri che sono state traslitterate nello stesso carattere, vengono ridotte ad una singola istanza di quel carattere.

    Se viene usato il modificatore /d, la LISTADISOSTITUZIONE viene interpretata proprio come specificato. Altrimenti, se la LISTADISOSTITUZIONE è più breve della LISTADIRICERCA, il carattere finale viene replicato fino alla sufficiente lunghezza. Se la LISTADISOSTITUZIONE è vuota, la LISTADIRICERCA viene replicata. Quest'ultima cosa è utile per contare i caratteri in una classe o per ridurre sequenze di caratteri in una classe.

    Esempi:

        $ARGV[1] =~ tr/A-Z/a-z/;    # trasforma tutto in minuscolo
        $cnt = tr/*/*/;             # conta gli asterischi in $_
        $cnt = $cielo =~ tr/*/*/;   # conta gli asterischi nel $cielo [asterisco in inglese e` 'star' che significa anche stella, NdR]
        $cnt = tr/0-9//;            # conta i numeri in $_
        tr/a-zA-Z//s;               # commercialista -> comercialista
        ($HOST = $host) =~ tr/a-z/A-Z/;
        tr/a-zA-Z/ /cs;             # trasforma i caratteri non alfabetici in spazi
    
    
        tr [\200-\377]
           [\000-\177];             # cancella l'ottavo bit

    Se vengono date più traslitterazioni per un carattere, viene utilizzata solo la prima:

        tr/AAA/XYZ/

    traslittera qualunque A con una X.

    Dato che la tabella di traslitterazione viene costruita a tempo di compilazione, né la LISTADIRICERCA, né la LISTADISOSTITUZIONE sono soggette ad interpolazione con il doppio quote. Il che vuol dire che se volete usare una variabile, dovete usare un eval():

        eval "tr/$vecchialista/$nuovalista/";
        die $@ if $@;
        eval "tr/$vecchialista/$nuovalista/, 1" or die $@;

    <<EOF >>
    Un tipo di quoting orientato alla linea è basato sulla sintassi di shell stile ``here-document'' [documento immediato, NdR]. A seguito di un << si specifica una stringa che termina il materiale quotato, e tutte le linee che seguono quella corrente fino alla stringa di terminazione costituiscono il valore di quell'elemento. La stringa di terminazione potrebbe essere sia un identificatore (una parola), o del testo quotato. Se quotato, il tipo di quote che si usa determina il trattamento del testo, come nel normale quote. Un identificatore non quotato funziona come un quote doppio. Se l'identificatore non è quotato, non ci devono essere spazi tra << e l'identificatore. (Se mettete uno spazio, sarà trattato come identificatore nullo, che è valido, il cui match avviene con la prima linea vuota). La stringa di terminazione deve esser presente (non quotata e non circondata da spazi) sulla linea di terminazione.
           print <<EOF;
        Il prezzo e` $Prezzo.
        EOF
           print << "EOF"; # lo stesso come sopra
        Il prezzo e` $Prezzo.
        EOF
           print << `EOC`; # esegue i comandi
        echo alto
        echo basso
        EOC
           print <<"pippo", <<"pluto"; # potete accatastarli
        Ho detto pippo.
        pippo
        Ho detto pluto.
        pluto
           miafunz(<< "QUESTO", 23, <<'QUELLO');
        Qui c'e` una linea
        o due.
        QUESTO
        e qui un'altra.
        QUELLO

    Non si dimentichi che va messo un punto e virgola alla fine dell'istruzione, Perl non sa che non si sta cercando di fare questo:

           print <<ABC
        179231
        ABC
           + 20;

    Se si vuole che la propria sintassi here-doc venga indentata con il resto del codice, dovrete rimuovere manualmente lo spazio iniziale da ciascuna linea:

        ($quote = <<'FINE') =~ s/^\s+//gm;
           La strada prosegue senza sosta,
           giu` dalla porta dove e` iniziata.
        FINE

    Se si usano here-doc all'interno di un costrutto delimitato, come in s///eg, il materiale quotato deve andare tutto all'interno del delimitatore finale. Quindi invece di

        s/questo/<<E . 'quello'
        altro
        E
         . 'piu '/eg;

    dovete scrivere

        s/questo/<<E . 'quello' 
         . 'piu'/eg; 
        altro 
        E

    Se l'identificatore terminatore si trova sull'ultima linea del programma, dovete assicurarvi che dopo l'identificatore ci sia ``un a capo''; altrimenti, Perl vi darà un avvertimento Can't find string terminator ``END'' anywhere before EOF... [Non riesco a trovare il terminatore di stringa ``END'' prima della fine del file..., NdR].

    Inoltre, le regole di quoting per l'identificatore non sono correlate alle regole di quoting del Perl - q(), qq(), e simili non sono supportati al posto di '' e "", e la sola interpolazione è per fare il backslash del carattere di quote:

        print << "abc\"def";
        sto testando...
        abc"def

    Per finire, le stringhe quotate non possono estendersi su più righe. La regola generale è che l'identificatore deve essere una stringa letterale. Ci si attenga a ciò e si dovrebbe essere al sicuro.

    Dettagli cruenti sui costrutti di parsing quotati

    Quando viene presentato con qualcosa che potrebbe avere svariate interpretazioni, Perl utilizza il principio DWIM (che è ``Do What I Mean'') [Fa quello che intendo, NdT] per scegliere l'interpretazione più probabile. Questa strategia ha così tanto successo che spesso i programmatori Perl non sospettano nulla riguardo all'ambivalenza di cià che scrivono. Ma da un momento all'altro, le idee del Perl differiscono in modo sostanziale da quello che voleva dire in tutta onestà l'autore.

    Questa sezione si auspica di chiarire come Perl gestisce i costrutti quotati. Sebbene la ragione più comune per imparare ciò è il districarsi nel labirinto delle espressioni regolari, dato che i passi iniziali del parsing sono gli stessi di quelli degli operatori di quoting, vengono discussi tutti assieme.

    La più importante regola di parsing in Perl è la prima discussa qui sotto: quando si processa un costrutto di quoting, Perl prima trova la fine di quel costrutto, poi ne interpreta il suo contenuto. Se si capisce questa regola, si potrebbe saltare il resto della sezione ad una prima lettura. Le altre regole sono suscettibili di contraddire le aspettative dell'utente molto meno frequentemente della prima regola.

    Alcuni passi, discussi in seguito, vengono eseguiti contemporanemanete, ma dato che i loro risultati sono gli stessi, si considerano individualmente. Per costrutti di quoting differenti, Perl esegue un differente numero di passi, da uno a cinque, ma questi passi sono eseguiti sempre nello stesso ordine.

    Trovare la fine
    Il primo passo è trovare la fine del costrutto quotato, sia si tratti di un delimitatore multicarattere "\nEOF\n" nel costrutto <<EOF, sia che si tratti di un / che termina un costrutto qq//, un ] che termina un qq[], o un > che termina un fileglob che inizia con <.

    Quando viene cercato un delimitatori a singolo carattere non simmetrico, come /, vengono omesse le combinazioni di \\ e \/. Comunque, quando si cerca un delimitatore a singolo carattere simmetrico come [, le combinazioni di \\, \], e \[ sono tutte trascurate, e i [, ] nidificati vengono anch'essi trascurati. Quando si cercano delimitatori multicarattere, non viene trascurato nulla.

    Per costrutti con delimitatori formati da tre parti (s///, y///, e tr///), la ricerca viene ripetuta una volta in più.

    Durante questa ricerca, non viene posta attenzione sulla semantica del costrutto. Quindi:

        "$hash{"$pippo/$pluto"}"

    o:

        m/ 
          pluto     # NON e` un commento, questo slash / termina m//!
         /x

    non forma un'espressione quotata legale. La parte quotata finisce sul primo " e /, ed il resto è un errore di sintassi. Dato che lo slash che termina m// era seguito da uno SPAZIO, l'esempio sopra non è m//x, ma piuttosto m// senza il modificatore /x. Quindi il # interno è interpretato come un letterale #.

    Anche su \c\ non viene posta attenzione durante questa ricerca. Quindi il secondo \ in qq/\c\/ viene interpretato come una parte di \/, e il seguente / non viene riconosciuto come delimitatore. Invece, si usino \034 o \x1c alla fine dei costrutti quotati.

    Rimozione del backslash prima dei delimitatori
    Durante il secondo passo, il testo tra il delimitatore iniziale e finale viene copiato in una locazione sicura, il \ viene rimosso dalle combinazioni che consistono di \ e il delimitatore - o i delimitatori, cioè entrambi i delimitatori di inizio e di fine devono essere differenti. Questa rimozione non accade per i delimitatori multicarattere. Va notato che la combinazione \\ viene lasciata intatta così come è stata trovata.

    A partire da questa fase, nel parsing non viene usata alcuna informazione sui delimitatori.

    Interpolazione
    Il prossimo passo è l'interpolazione del testo ottenuto, il quale è ora indipendente dai delimitatori. Ci sono quattro casi differenti.
    <<'EOF', m'', s''', tr///, y///
    Non viene effettuata alcuna interpolazione.

    '', q//
    La sola interpolazione è la rimozione di \ dalla coppia \\.

    "", ``, qq//, qx//, <file*glob>
    \Q, \U, \u, \L, \l (possibilmente accoppiati con \E) sono convertiti al corrispondente costrutto Perl. Quindi, "$pippo\Qpaperino$pluto" viene convertito internamente in $pippo . (quotemeta("paperino" . $pluto)). Le altre combinazioni sono rimpiazzate con espansioni appropriate.

    Va sottolineato che qualsiasi cosa tra \Q e \E viene interpolata alla stessa maniera. Qualcosa come "\Q\\E" non ha alcun \E al suo interno. Invece, ha \Q, \\, e E, cosà che il risultato sia lo stesso che per "\\\\E". Come regola generale, i backslash tra \Q e \E potrebbero portare a risultati controintuitivi. Cosà, "\Q\t\E" viene convertito in quotemeta("\t"), il quale è lo stesso che "\\\t" (dato che TAB non è alfanumerico). Va anche notato che:

      $str = '\t';
      return "\Q$str";

    può essere più vicina alla probabile intenzione di chi ha scrtto "\Q\t\E".

    Scalari interpolati e array vengono convertiti internamente con gli operatori di concatenazione join e .. Quindi, "$pippo XXX '@arr'" diventa:

      $pippo . " XXX '" . (join $", @arr) . "'";

    Tutte le operazioni qui sopra vengono effettuate simultaneamente, da sinistra a destra.

    Dato che il risultato di "\Q STRINGA \E" ha tutti i metacaratteri quotati, non c'è modo di inserire un letterale $ o @ dentro una coppia \Q\E. Se protetto da un \, $ sarà quotato per diventare "\\\$"; se non è così, viene interpretato come l'inizio di uno scalare interpolato.

    Va anche notato che il codice di interpolazione ha bisogno di prendere una decisione su dove finisca lo scalare interpolato. Per esempio, sia "a $b -> {c}" significa effettivamente:

      "a " . $b . " -> {c}";

    oppure:

      "a " . $b -> {c};

    Il più delle volte, il testo più lungo possibile che non include degli spazi tra i componenti e che contiene parentesi graffe o quadre corrispondenti. Poiché l'esito potrebbe essere determinato in base ad una analisi di stime euristiche, il risultato non è prevedibile a priori. Fortunatamente, di solito va bene nei casi ambigui.

    ?RE?, /RE/, m/RE/, s/RE/pippo/,
    L'elaborazione di \Q, \U, \u, \L, \l, e l'interpolazione avviene (quasi) come con il costrutto qq//, ma la sostituzione di \ seguito da un carattere speciale delle espressioni regolari (incluso \) non viene eseguita. Inoltre, dentro un (?{BLOCCO}), (?# commento ), e un commento # in una espressione regolare con //x, non viene eseguita alcuna elaborazione. Questo è il primo passo nel quale è rilevante la presenza del modificatore //x.

    L'interpolazione ha diverse stranezze: $|, $(, e $) non vengono interpolati, e i costrutti $var[QUALCOSA] sono votati (da disparati diversi stimatori) ad essere o un elemento di un array o un $var seguito da una espressione regolare alternativa. Questo è il caso nel quale la notazione ${arr[$pluto]} è particolarmente utile: /${arr[0-9]}/ è interpretata come l'elemento dell'array -9, non come un'espressione regolare dalla variabile $arr seguita da una cifra, che sarebbe l'interpretazione di /$arr[0-9]/. Dato che si possono verificare votazioni tra differenti stimatori, il risultato non è predicibile.

    È a questo punto che \1 viene convertito a malincuore in $1 nel testo di sostituzione di s/// per correggere gli incorregibili sed hacker che non hanno ancora trovato la giusta espressione idiomatica. Viene emesso un avvertimento se sulla linea di comando sono stati impostati la direttiva use warnings o il flag -w (cioè, la variabile $^W).

    La mancanza di elaborazione di \\ crea delle specifiche restrizioni sul testo post-processato. Se il delimitatore è /, nel risulato di questo passo non si può avere la combinazione \/. / terminer&agreve; l'espressione regolare, \/ sarà ripulita da / nel passo precedente, e \\/ verrà lasciato così com'è. Dato che dentro ad un'espressione regolare / è equivalente a \/, ciò non ha importanza a meno che il delimitatore non sia un carattere speciale per il motore delle espressioni regolari, come in s*pippo*pluto*, m[pippo], o ?pippo?; oppure un carattere alfanumerico, come in:

      m m ^ a \s* b mmx;

    Nell'espressione regolare qui sopra, che è intenzionalmente offuscata per illustrare l'esempio, il delimitatore è m, il modificatore è mx, e dopo che il backslash viene rimosso, la RE è la stessa come per m/ ^ a \s* b /mx. C'è più di un motivo per il quale siamo incoraggiati a restringere i delimitatori a scelte non alfanumeriche e senza spazi vuoti.

    Questo passo è l'ultimo per tutti i costrutti tranne che per le espressioni regolari, le quali vengono elaborate più avanti.

    Interpolazione di espressioni regolari
    I passi precedenti venivano eseguiti durante la compilazione del codice Perl, ma questo avviene a tempo di esecuzione sebbene, se opportuno, potrebbe essere ottimizzato per esser calcolato a tempo di compilazione. Dopo la pre-elaborazione descritta sopra, e possibilmente dopo la valutazione nel caso siano coinvolti concatenazione, unione, traduzione dei case [delimitatori, NdT], o il mataquoting, la stringa risultante viene passata per la compilazione al motore delle espressioni regolari.

    Qualunque cosa accada nel motore delle espressioni regolari, potrebbe essere discusso meglio in perlre, ma per ragioni di continuità, dobbiamo farlo anche qui.

    Questo è un altro passo nel quale è rilevante la presenza del modificatore //x. Il motore delle espressioni regolari scansiona la stringa da sinistra a destra e la converte in un automa a stati finiti.

    I caratteri con backslash sono o rimpiazzati con le corrispondenti stringhe letterali (come con \{), oppure generano dei nodi speciali nell'automa a stati finiti (come con \b). I caratteri speciali per il motore delle espressioni regolari (come |) generano i nodi corrispondenti o gruppi di nodi. I commenti come (?#...) vengono ignorati. Tutto il resto viene o convertito in delle stringhe letterali di cui effettuare il match, o altrimenti viene ignorato (come avviene per lo spazio vuoto e i commenti stile # se è presente //x).

    Il parsing del costrutto della classe di caratteri tra parentesi quadre, [...], è piuttosto differente rispetto alla regola utilizzata per il resto del pattern. Il terminatore di questo costrutto viene trovato utilizzando le stesse regole usate per trovare il terminatore di un costrutto delimitato da {}, l'unica eccezione è che ] immediatamente seguito da [ viene trattato come se fosse preceduto da un backslash. Analogamente, il terminatore (?{...}) viene trovato usando le stesse regole usate per trovare il terminatore di un costrutto delimitato da {}.

    È possibile ispezionare sia la stringa data al motore delle espressioni regolari che l'automa a stati finiti risultante. Si vedano gli argomenti debug/debugcolor nella direttiva use re, così come per il parametro -Dr sulla linea di comando di Perl in perlrun/``Parametri su linea di comando''.

    Ottimizzazioni delle espressioni regolari
    Questo passo viene elencato solo per completezza. Dato che non cambia la semantica, i dettagli di questo passo non sono documentati e sono soggetti a cambiamenti senza preavviso. Questo passo viene eseguito sull'automa a stati finiti generato durante il passo precedente.

    È a questo punto che split() ottimizza silenziosamente /^/ in /^/m.

    Operatori di I/O >>

    Ci sono diversi operatori di I/O che sarebbe necessario conoscere.

    Una stringa racchiusa da backtick (accenti gravi) subisce inizialmente una interpolazione a doppio quote. Poi viene interpretata come un comando esterno, e l'output di quel comando è il valore della stringa dei backtick, come in una shell. In contesto scalare, viene restituita una stringa singola che consiste di tutto l'output. In contesto di lista, viene restituita una lista di valori, uno per ogni linea di output. (Potete impostare $/ per utilizzare un terminatore di linea differente). Il comando viene eseguito ogni volta che viene valutato lo pseudo-letterale. Il valore di stato del comando viene restituito in $? (per l'interpretazione di $? si veda perlvar). Diversamente da csh, non viene effettuata una traduzione sui dati restituiti: gli a capo rimangono a capo. Diversamente da una qualsiasi shell, i quote singoli non proteggono i nomi di variabile nel comando dall'interpolazione. Per passare un simbolo letterale di dollaro alla shell, avete bisogno di nasconderlo con un backslash. La forma generalizzata dei backtick è qx//. (Perché anche i backtick vengono sempre sottoposti ad espansione da parte della shell, per le problematiche di sicurezza si veda perlsec).

    In contesto scalare, valutare un filehandle racchiuso nelle parentesi angolari, raccoglie la prossima linea da quel file (ritorno a capo incluso), o undef alla fine del file o a causa di un errore. Quando $/ è impostato ad undef (a volte conosciuto come modalità file-slurp) e il file è vuoto, la prima volta restituisce '', seguito successivamente da undef.

    Di solito è necessario assegnare il valore restituito ad una variabile, ma c'è una situazione nella quale avviene un assegnamento automatico. Se e solo se il simbolo in input è la sola cosa all'interno della condizione di un while (anche se travestito da for(;;)), il valore viene automaticamente assegnato alla variabile globale $_, distruggendo qualsiasi cosa ci fosse in precedenza. (Questa vi potrebbe sembrare una cosa strana, ma dovrete usare il costrutto in quasi tutti gli script Perl che scriverete). La variabile $_ non viene localizzata in modo implicito. Se si vuole che ciò accada, dovrete mettere un local $_; prima del ciclo.

    Le linee seguenti sono equivalenti:

        while (defined($_ = <STDIN>)) { print; }
        while ($_ = <STDIN>) { print; }
        while (<STDIN>) { print; }
        for (;<STDIN>;) { print; }
        print while defined($_ = <STDIN>);
        print while ($_ = <STDIN>);
        print while <STDIN>;

    Anche questo si comporta in maniera simile, ma fa a meno di $_ :

        while (my $linea = <STDIN>) { print $linea }

    In questi costrutti di ciclo, il valore assegnato (se l'assegnamento è automatico o esplicito) viene testato per vedere se è definito. Il test defined evita i problemi nei quali la linea ha un valore stringa che sarebbe trattato come falso dal Perl, per esempio un ``'' o un ``0'' senza ritorno a capo finale. Se davvero si vuole terminare il ciclo per tali valori, allora devono essere testati esplicitamente:

        while (($_ = <STDIN>) ne '0') { ... }
        while (<STDIN>) { last unless $_; ... }

    In altri contesti booleani, <filehandle senza un esplicito test defined o un confronto, verrà segnalato un avvertimento se vengono utilizzati la direttiva use warnings o il parametro -w sulla linea di comando (la variabile $^W).

    
    I filehandle STDIN, STDOUT, e STDERR sono predefiniti. (Funzioneranno anche i 
    filehandle C<stdin>, C<stdout>, e C<stderr> eccetto che all'interno dei 
    package, dove verrebbero interpretati come identificatori locali
    anzichE<eacute> globali). Tra le altre cose, possono esser creati dei filehandle addizionali 
    con la funzione open(). Per i dettagli si vedano L<perlopentut> e L<perlfunc/open>.
    X<stdin> X<stdout> X<sterr>

    Se un <FILEHANDLE> viene usato in un contesto che sta cercando una lista, viene restituita una lista comprendente tutte le linee di input, una linea per ciascun elemento della lista. In questo modo è facile che ciò si sviluppi in un ammontare di spazio dati piuttosto grande, quindi usatelo con attenzione.

    <FILEHANDLE> potrebbe anche esser scritto come readline(*FILEHANDLE). Si veda perlfunc/readline.

    Il filehandle nullo <> è speciale: può esser usato per emulare il comportamento di sed e awk. L'input da <> viene o dallo standard input, o da ciascun file elencato sulla linea di comando. Ecco come funziona: la prima volta che <> viene valutato, viene controllato l'array @ARGV, e se è vuoto, $ARGV[0] viene impostato a ``-'', così che quando viene aperto, darà lo standard input. Poi l'array @ARGV viene processato come una lista di nomi di file. Il ciclo

        while (<>) {
            ...         # codice per ciascuna linea
        }

    è equivalente al seguente pseudo codice stile Perl:

        unshift(@ARGV, '-') unless @ARGV;
        while ($ARGV = shift) {
            open(ARGV, $ARGV);
            while (<ARGV>) {
                ...     # codice per ciascuna linea
            }
        }

    eccetto il fatto che non è cosà scomodo da scrivere, ed in effetti funziona. Esegue davvero lo shift sull'array @ARGV e mette il nome del file corrente dentro la variabile $ARGV. Internamente esso utilizza anche il filehandle ARGV; <> è solamente un sinonimo per <ARGV>, che è magico. (Lo pseudo codice sopra non funziona perché tratta <ARGV> come non-magico).

    È possibile modificare @ARGV prima del primo <> finché l'array termina contendendo la lista dei nomi di file che si vogliono veramente. I numeri di linea ($.) continuano come se l'input fosse un unico grande file felice. Per capire come reimpostare i numeri di linea in ogni file si veda l'esempio in perlfunc/eof.

    Se si desidera impostare @ARGV alla propria lista di file, fatelo in anticipo. Se non viene fornito @ARGV, questo inserisce in @ARGV tutti file di puro testo:

        @ARGV = grep { -f && -T } glob('*') unless @ARGV;

    Si può anche utilizzare @ARGV per redirigere a comandi esterni tramite pipe. Per esempio, questo filtra automaticamente i file compressi, passati come argomento, tramite gzip:

        @ARGV = map { /\.(gz|Z)$/ ? "gzip -dc < $_ |" : $_ } @ARGV;

    Se si desidera passare dei parametri [le opzioni da riga di comando come --verbose, NdT] ai vostri script, potete utilizzare uno dei moduli Getopt o inserire anteriormente un ciclo, in questo modo:

        while ($_ = $ARGV[0], /^-/) {
            shift;
            last if /^--$/;
            if (/^-D(.*)/) { $debug = $1 }
            if (/^-v/)     { $verboso++  }
            # ...       # altri parametri
        }
        while (<>) {
            # ...       # codice per ciascuna linea
        }

    Il simbolo <> restituirà undef per la fine-del-file una sola volta. Se successivamente lo si chiama ancora una volta, assumerà che stiate processando un'altra lista in @ARGV, e se non avete impostato @ARGV, leggerà  l'input da STDIN.

    Se quello che le parentesi angolari contengono è semplicemente una variabile scalare (per esempio <$pippo>), allora quella variabile contiene il nome del filehandle dal quale verrà letto l'input, o il suo typeglob, o un riferimento allo stesso. Per esempio:

        $fh = \*STDIN;
        $linea = <$fh>;

    Se ciò che sta tra le parentesi angolari non è né un filehandle né una semplice variabile scalare contenente il nome di un filehandle, typeglob, o riferimento a typeglob, allora viene interpretato come il modello di un nome di file che va espanso [filename pattern globbing, NdR] e, a seconda del contesto, viene restituito o una lista di nomi di file oppure il prossimo nome del file nella lista. Questa distinzione viene determinata su base sintattica. Cioè <$x> è sempre una readline() da un handle indiretto, ma <$hash{chiave}> è sempre un glob(). Questo perché $x è una semplice variabile scalare, ma $hash{chiave} no: è un elemento di hash. Anche <$x > (si noti lo spazio in più) viene trattato come glob("$x "), non come readline($x).

    Prima viene eseguito un livello di interpretazione a doppio quote, ma non è possibile dire <$pippo> perché questo è un filehandle indiretto, come spiegato nel paragrafo precedente. (Nelle vecchie versioni di Perl, i programmatori inserirebbero delle parentesi graffe per forzare l'interpretazione a glob del nome di file: <${pippo}>. Oggi, viene considerato più pulito chiamare direttamente la funzione interna: glob($pippo), che in primo luogo è probabilmente la via giusta per farlo). Per esempio:

        while (<*.c>) {
            chmod 0644, $_;
        }

    è approssivamente equivalente a:

        open(PIPPO, "echo *.c | tr -s ' \t\r\f' '\\012\\012\\012\\012'|");
        while (<PIPPO>) {
            chomp;
            chmod 0644, $_;
        }

    salvo che il glob venga effettivamente eseguito internamente utilizzando l'estensione standard File::Glob. Naturalmente, la via più breve per fare quanto sopra è:

        chmod 0644, <*.c>;

    Un (file)glob valuta il suo argomento (incorporato) solo quando sta iniziando una nuova lista. Tutti i valori devono essere letti prima che la lista venga reinizializzata. In contesto di lista, questo non è importamente, perché saranno comunque ottenuti tutti automaticamente. Tuttavia, in contesto scalare l'operatore restituisce il valore successivo ogni volta che viene chiamato, oppure undef quando la lista è finita. Come con le letture di un filehandle, viene generato un defined automatico quando il glob si presenta nella parte di test del while, perché la restituzione di un glob legale (ad esempio un file chiamato 0) terminerebbe altrimenti il ciclo. Ancora, undef viene restituito una volta sola. Così se vi state aspettando un solo valore da un glob, è molto meglio dire

        ($file) = <rigurgito*>;

    che

        $file = <rigurgito*>;

    perché quest'ultimo alternerebbe la restituizione di un nome di un file con un valore falso.

    Se state cercando di fare l'interpolazione di una variabile, è decisamente meglio usare la funzione glob(), perché la vecchia notazione potrebbe indurre le persone a confondersi con la notazione a filehandle indiretto.

        @file = glob("$dir/*.[ch]");
        @file = glob($file[$i]);

    Constant Folding [Trasformazione per semplificare o rendere più efficiente il codice, NdR]

    Come il C, Perl esegue una certa quantità di valutazioni di espressioni a tempo di compilazione ogni volta che determina che tutti gli argomenti di un operatore sono statici e non hanno effetti collaterali. In particolare, la concatenazione di una stringa avviene a tempo di compilazione tra i letterali che non fanno una sostituzione di variabile. Anche l'interpolazione del backslash avviene a tempo di compilazione. Si può dire

        'Abbiamo fatto l'Italia' . "\n" .
        'ora dobbiamo fare gli italiani.'

    e internamente tutto questo viene ridotto ad una (unica) stringa. Allo stesso modo, se si dice

        foreach $file (@nomideifile) {
            if (-s $file > 5 + 100 * 2**16) {  }
        }

    il compilatore pre-calcolerà il numero che quell'espressione rappresenta, in maniera che non debba farlo l'interprete.

    I no-op

    Perl non ha ufficialmente un operatore no-op [che non fa nulla, NdR], ma le semplici costanti 0 e 1 sono casi speciali che non producono degli avvertimenti in constesto vuoto, in modo ad esempio da poter tranquillamente fare

        1 while pippo();

    Operatori bit a bit su stringhe

    Stringhe di bit di qualunque dimensione possono essere manipolate dagli operatori bit a bit su stringhe (~ | & ^).

    Se gli operandi di un operatore bit a bit binario sono delle stringhe di dimensioni differenti, gli operatori | e ^ funzionano come se l'operando più corto avesse dei bit impostati a zero sulla destra, mentre l'opeartore & funziona come se l'operando più lungo fosse troncato alla lunghezza di quello più corto. La granularità per questo tipo di estensione o troncamento è di uno o più byte.

        # esempio basato su ASCII 
        print "j p \n" ^ " a h";            # stampa "JAPH\n" [acronimo di Just Another Perl Hacker: semplicemente un altro hacker perl, NdR]
        print "JA" | "  ph\n";              # stampa "japh\n"
        print "japh\nJunk" & '_____';       # stampa "JAPH\n";
        print 'p N$' ^ " E<H\n";            # stampa "Perl\n";

    Se si ha intenzione di manipolare stringhe di bit, siate certi che si intenda fornire stringhe di bit: se un operando è un numero, ciò implicherà una operazione bit a bit numerica. Si può evidenziare in modo esplicito il tipo di operazione che intendete, utilizzando "" o 0+, come nell'esempio qui sotto.

        $pippo =  150  |  105;  # produce 255  (0x96 | 0x69 e` 0xFF)
        $pippo = '150' |  105;  # produce 255
        $pippo =  150  | '105'; # produce 255
        $pippo = '150' | '105'; # produce la stringa '155' (in ASCII)
        $paperino = 0+$pippo & 0+$pluto;    # entrambi gli opearndi sono esplicitamente numerici
        $topolino = "$pippo" ^ "$pluto";    # entrambi gli opearndi sono esplicitamente delle stringhe

    Per informazioni su come manipolare singoli bit in un vettore di bit si veda perlfunc/vec.

    Aritmetica intera

    Di default, Perl assume di dover eseguire gran parte delle operazioni aritmetiche in virgola mobile. Ma dicendo

        use integer;

    si può dire al compilatore che va bene utilizzare le operazioni intere (se se la sente) da qui alla fine del BLOCCO in cui è racchiuso. Un BLOCCO innestato potrebbe annullare ciò dicendo

        no integer;

    che dura fino alla fine di quel BLOCCO. Si noti che questo non significa che tutto è unicamente un intero, ma solo che Perl può usare operazioni intere, se se la sente. Per esempio, anche sotto use integer, se usate sqrt(2), otterrette ancora 1.4142135623731 o giù di lì.

    Usato sui numeri, gli operatori bit a bit (``&'', ``|'', ``^'', ``~'', ``<<'', e ``>>'') producono sempre risultati interi. (Ma date un'occhiata anche a Operatori bit a bit su stringhe.) Tuttavia, per questi operatori use integer ha ancora senso. Di default, i loro risultati vengono interpretati come interi senza segno, ma se è in vigore use integer, i loro risultati sono interpretati come interi con segno. Per esempio, ~0 di solito restituisce un valore intero molto grande. use integer; ~0, invece, è -1 su macchine a complemento a due.

    Aritmetica in virgola mobile

    Mentre use integer fornisce solamente aritmetica per interi, non c'è un meccanismo analogo per fornire un arrotondamento automatico o troncamento ad un certo numero di cifre decimali. Per arrotondare ad un certo numero di cifre, sprintf() o printf() sono solitamente la via più semplice. Si veda perlfaq4.

    I numeri in virgola mobile sono solo delle approssimazioni a qualcosa che un matematico chiamerebbe numeri reali. Ci sono infiniti numeri reali rispetto ai float, quindi alcuni spigoli devono esser smussati. Per esempio:

        printf "%.20g\n", 123456789123456789;
        #         produce 123456789123456784

    Fare il test di uguaglianza o disuguaglianza per un numero in virgola mobile non è una buona idea. Qui presentiamo un (relativamente costoso) trucco per confrontare se due numeri in virgola mobile sono uguali rispetto ad un precisato numero di cifre decimali. Per un trattamento più robusto di questo argomento si veda Knuth, volume II.

        sub fp_uguali {
            my ($X, $Y, $NUMERO_CIFRE) = @_;
            my ($tX, $tY);
            $tX = sprintf("%.${NUMERO_CIFRE}g", $X);
            $tY = sprintf("%.${NUMERO_CIFRE}g", $Y);
            return $tX eq $tY;
        }

    Il modulo POSIX (parte della distribuzione standard del Perl) implementa ceil(), floor(), e altre funzioni matematiche e trigonometriche. Il modulo Math::Complex (parte della distribuzione standard del Perl) definisce delle funzioni matematiche che funzionano sia sui reali che sui numeri immaginari. Math::Complex non è così efficiente come POSIX, ma POSIX non può funzionare con i numeri complessi.

    L'arrotondamento in applicazioni finanziarie ha serie implicazioni e il metodo di arrotondamento utilizzato dovrebbe essere specificato con precisione. In questi casi, probabilmente è meglio non fidarsi di qualsiasi sia il sistema di arrotondamento utilizzato dal Perl, bensì implementarsi la funzione di arrotondamento della quale si ha bisogno.

    Grandi Numeri

    I moduli standard Math::BigInt e Math::BigFloat forniscono operatori aritmetici a precisione variabile e operatori overloaded [con più di un significato della loro funzionalità, NdR], sebbene attualmente siano abbastanza lenti. Al costo di un po' di spazio e di una considerevole perdita in velocità, vi evitano le trappole associate con rappresentazioni a precisione limitata.

        use Math::BigInt;
        $x = Math::BigInt->new('123456789123456789');
        print $x * $x;
        # stampa +15241578780673678515622620750190521

    Ci sono diversi moduli che vi permettono di eseguire calcoli con (limitati solo da memoria e tempo di cpu) precisione illimitata o fissa. Ci sono anche dei moduli non standard che forniscono delle implementazioni più veloci attraverso librerie C esterne.

    Segue un breve, ma incompleto sommario:

        Math::Fraction              grandi, illimitate frazioni come 9973 / 12967
        Math::String                tratta sequenze di numeri come stringhe
        Math::FixedPrecision        calcola con precisione fissa
        Math::Currency              per calcoli monetari
        Bit::Vector                 manipola velocemente vettori di bit (usa il C)
        Math::BigIntFast            incapsula Bit::Vector per numeri grandi 
        Math::Pari                  fornisce accesso alla libreria C Pari
        Math::BigInteger            usa una libreria C esterna
        Math::Cephes                usa la libreria C Cephes (non per numeri grandi)
        Math::Cephes::Fraction      frazioni attraverso la libreria Cephes
        Math::GMP                   un altro che usa una libreria C esterna

    Si scelga con buon senso.


    TRADUZIONE

    Versione

    La versione su cui si basa questa traduzione è ottenibile con:

       perl -MPOD2::IT -e print_pod perlop

    Per maggiori informazioni sul progetto di traduzione in italiano si veda http://pod2it.sourceforge.net/ .

    Traduttore

    Traduzione a cura di Daniele Ludovici.

    Revisore

    Revisione a cura di dree, dakkar, dada.


    Mon Jun 11 22:02:17 2012