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.

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. 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 (ass. 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. Vedere 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 seguito da una parentesi aperta come token 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($foo, exit);  # Decisamente non quello che si vuole.
    print $foo, exit;   # Neanche questo.
    # Queste eseguono print prima di valutare exit:
    (print $foo), exit; # Questo va bene.
    print($foo), exit;  # Oppure questo.
    print ($foo), exit; # anche questo.

Si noti anche che

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

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

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

Per ottenere il risultato corretto bisogna scrivere:

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

Si veda anche Operatori unari con nome per un ulteriore approfondimento.

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

Vedere anche Virgolette e operatori simili 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 o simbolico 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). Vedere perlreftut e perlref.

Altrimenti, 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 cui è stato applicato bless) oppure un nome di classe (ossia il nome di un package). Vedere 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

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

    print ++($foo = '99');      # stampa '100'
    print ++($foo = 'a0');      # stampa 'a1'
    print ++($foo = 'Az');      # stampa 'Ba'
    print ++($foo = '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 vuoldire -(2**4), non (-2)**4. È implementato utilizzando la funzione C pow(3), che internamente utilizza dei double (numeri in virgola mobile).

Operatori unari simbolici

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

Il ``-'' unario effettua una negazione aritmetica se l'operando è numerico. Se l'operando è un identificatore, viene restituita una stringa consistente nel segno meno seugito dall'identificatore. Altrimenti, 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 a "-pippo". Se, però, la stringa comincia con con carattere non alfabetico (a parte + o -), Perl proverà a convertirla in un numero e effettuare la negazione aritmetica. Se la stringa non può essere convertita correttamente in un numero, Perl emetterà l'avviso Argument ``the string'' isn't numeric in negation (-) at ... (``L'argomento non è numerico durante una negazione (-) alla riga...'').

Il ``~'' unario effettua una negazione bit a bit, ossia il complemento ad 1. Ad esempio, 0666 & ~027 è uguale a 0640 (vedere anche Aritmetica Intera e Operatori di bit su stringhe). Da notare 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 in parentesi che sarebbe altrimenti interpretata come lista dei parametri della funzione (vedere gli esempi sopra alla voce Termini e operatori di lista (associatività a sinistra)).

Il ``\'' unario crea un riferimento a qualunque cosa segua. Vedere perlreftut e perlref. Quest'operazione non è da confondere con l'utilizzo della backslash all'interno di stringhe, per quanto entrambe le forme implichino la nozione di proteggere ciò che segue dall'interpolazione del loro valore.

Operatori di match

Il ``=~'' binario effettua un pattern match su un'espressione scalare. Alcune operazioni agiscono su, o modificano, la stringa contenuta in $_ per default. 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 lista dipende dalla singola operazione. Vedere Regexp Quote-Like Operators per i dettagli.

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

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

Operatori di moltiplicazione

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). Si noti che se si sta utilizzando il pragma integer, l'operatore ``%'' utilizza direttamente il corrispondente operatore C, come 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 lista, se l'operando di sinistra è posto fra parentesi, ripete la lista.

    print '-' x 80;             # stampa una riga di trattini
    print "\t" x ($tab/8), ' ' x ($tab%8);      # [?tab over]
    @uni = (1) x 80;            # una lista di 80 uni
    @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 ruotato a sinistra del numero di bit specificato dall'operando di destra. Gli operandi dovrebbero essere interi (vedere anche Integer Arithmetic).

Il ``>>'' binario restituisce il valore dell'operando di sinistra ruotato a destra del numero di bit specificato dall'operando di destra. Gli operandi dovrebbero essere interi (vedere anche Integer Arithmetic).

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

Il risultato di oltrepassare il limite consentito per gli integer non è definito, poiché non è definito neanche in C. In altre parole, usando integer 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 parentesi opzionali.

Se qualsiasi operatore list (print(), ecc.) o qualunque operatore unario (chdir(), ecc.) e' seguito da una parentesi come token 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 $foo    || die;   # (chdir $foo) || die
    chdir($foo)   || die;   # (chdir $foo) || die
    chdir ($foo)  || die;   # (chdir $foo) || die
    chdir +($foo) || die;   # (chdir $foo) || die

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

    chdir $foo * 20;    # chdir ($foo * 20)
    chdir($foo) * 20;   # (chdir $foo) * 20
    chdir ($foo) * 20;  # (chdir $foo) * 20
    chdir +($foo) * 20; # chdir ($foo * 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 (Leftward).


=head2 Operatori di confronto

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 NaNs (not-a-numers) come valori numerici, usando questi con ``<=>'' restituisce undef. NaN non è ``<'', ``=='', ``>'', ``<='' o ``>='' a qualsiasi cosa (anche NaN), quindi questi 5 restituiscono false. NaN != NaN restituisce un valore vero, così 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 qui" 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 di 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.

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

And bit a bit

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

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

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

Or bit a bit e Or esclusivo

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

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

Notate 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ò vuol dire che, se l'operando a sinistra è falso, l'operando a destra non verrà valutato. Il contesto scalare o quello lista viene propagato sulla valutazione del secondo operando, se questa avviene. 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 torna 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 e' vero, l'operatore a destra non sarà valutato. Il contesto scalare o quello lista viene propagato sulla valutazione del secondo operando, se questa avviene.

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

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

In particolare, questo significa che non dovreste utilizzare questo metodo per selezionare tra due aggregati per l'assegnamento:

    @a = @b || @c;      # questo E<egrave> sbagliato
    @a = scalar(@b) || @c;  # E<egrave> stato interpretato cosE<igrave>
    @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 gripe(), next LINE;

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

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

Usare ``or'' per l'assegnamento corrisponde a fare inverosimilmente ciò che si vuole; si veda sotto.

Operatori di Rango

L'operatore binario ``..'' è l'operatore di rango, che si comporta come due operatori realmente differenti in base al contesto di utilizzazione. In contesto lista, esso ritorna 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 rango è utile per scrivere foreach (1..10) cicli e per fare operazioni di slice sugli array. Nell'implementazione corrente, non viene creato un array temporaneo quando l'operatore di rango viene utilizzato come espressione nei cicli di tipo foreach, ma nelle più vecchie versioni di Perl potrebbe sprecare molta memoria quando scrivete qualcosa come questo:

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

L'operatore di rango funziona anche sulle stringhe, usando il magico auto-incremento, 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 personale stato booleano. Esso è falso finchè il suo operando a sinistra è falso. Una volta che l'operando a sinistra diventa vero, l'operatore di rango rimane vero finchè l'operando a destra è vero, DOPODICHÈ l'operatore di rango diventa falso di nuovo. Non diventa falso fino alla prossima volta che l'operatore di rango verrà valutato. Esso può testare l'operando di 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 giusto come ``..'' fa.

L'operando di destra non viene valutato quando l'operatore si trova nello stato di falso, e l'operando di 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 resettato per ogni rango incontrato. Il numero di sequenza finale in un rango ha appesa ad esso la stringa ``E0'', la quale non altera il suo valore numerico, ma vi offre un qualcosa di utile per cercarla se volete escludere un estremo. 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 dell'``input line'' corrente (la variabile $.).

Per esser pignoli, il confronto è realmente int(EXPR) == int(EXPR), ma è solamente un problema se usi un'espressione in virgola mobile; quando implicitamente usate $. come descrito nel precedente paragrafo, il confronto tra int(EXPR) == int($.) diventa un problema quando $. è settato 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 100 di un file
    a

Operatore condizionale

Il ``?:'' ternario è l'operatore condizionale, proprio come in C. Funziona grossomodo come un if-then-else (se-allora-altrimenti). 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 di questo:

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

Che dovrebbe probabilmente essere scritto più semplicemente così:

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

Operatori di Assegnamento >> >= >>>

``='' è il solito operatore di assegnamento.

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

    $a += 2;

equivale a

    $a = $a + 2;

although without duplicating any side effects that dereferencing the lvalue might trigger, such as from 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 di assegnamento.

Diversamente dal C, l'operatore di assegnamento scalare produce un valore sinistro 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:

    ($tmp = $global) =~ tr [A-Z] [a-z];

Così come,

    ($a += 2) *= 3;

è equivalente a

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

Analogamente, l'assegnamento di una lista in contesto lista produce la lista di valori sinistri assegnati, e un assegnamento 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 butta il valore, poi valuta il suo argomento a destra e lo restituisce.

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

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

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

è equivalente a:

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

Esso NON è:

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

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

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 lista (associatività a destra)

Sulla lato destro di un operatore lista, esso ha una precedenza molto bassa, tale che esso controlla tutte le espressioni separate da virgola che 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 opeatori lista senza il bisogno di ulteriori parentesi:

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

Si veda anche la discussione sugli operatori lista in Terms and List Operators (Leftward).

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 precedenze molto basse. Questo significa che esso corto-circuita: i.e., 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 precedenze molto basse. Questo lo rende molto utile per il controllo di flusso

    print FH $data      or die "Non posso scrivere in FH: $!";

Questo significa che esso cortocircuita: i.e., 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 controllo di flusso.

    $a = $b or $c;      # bug: questo E<egrave> sbagliato
    ($a = $b) or $c;    # significa veramente questo
    $a = $b || $c;      # meglio scritto in questo modo

Comunque, quando si trova in un assegnamento in contesto lista e voi state cercando di utilizzare ``||'' per controllo di flusso, probabilmente avrete bisogno di ``or'' in modo che l'assegnamento prende precedenza più alta.

    @info = stat($file) || die;     # oops, stat in "senso" scalare
    @info = stat($file) or die;     # meglio, ora @info prende ciE<ograve> che gli spetta

Ma ancora, potreste usare le parentesi.

    ( @info = stat($file) ) || die; # aggiunto da me

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

Opearatori del C che mancano nel Perl

Ecco cosa ha il C che non c'è in Perl:

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

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

    (TYPE)
  • Virgolette e operatori simili >>

    Mentre solitamente pensiamo ai quote come a dei valori letterali, in Perl essi funzionano come operatori, fornendo varie tipologie di interpolazione e capacità di pattern matching. Perl fornisce caratteri di quote usuali per questi comportamenti, ma vi fornisce anche una strada per scegliere il vostro carattere di quote per uno qualsiasi di essi. Nella seguente tabella, un {} rappresenta una coppia di delimitatori che avete scelto.

        Usuale  Generico        Significato      Interpola
            ''       q{}          Letterale           no
            ""      qq{}          Letterale           sE<igrave>
            ``      qx{}          Comando             sE<igrave>*
                    qw{}         Lista di parole  no
            //       m{}       Pattern match          sE<igrave>*
                    qr{}          Pattern             sE<igrave>*
                     s{}{}      Sostituzione          sE<igrave>*
                    tr{}{}    Traslitterazione        no (ma si veda sotto)
            <<EOF                 here-doc            sE<igrave>*
            * se il delimitatore non E<egrave> ''.

    I delimitatori senza graffe usano lo stesso carattere a prua e a poppa, ma i quattro tipi di parentesi (tonde, angolari, quadrate, graffe) si annideranno tutte, il che significa

        q{foo{bar}baz}

    è lo stesso che

        'foo{bar}baz'

    Notate, 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 ad esser 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. q#foo# è parsato come stringa foo, mentre q #foo# è l'operatore q seguito da un commento. Il suo argomento sarà preso dalla prossima linea. Questo vi permette di scrivere:

        s {foo}  # Rimpiazza foo
          {bar}  # con bar.

    Le seguenti sequenze di escape sono disponibili in costrutti che interpolano e nella traslitterazione.

        \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        octal char      (ESC)
        \x1b        hex char        (ESC)
        \x{263a}    wide hex char   (SMILEY)
        \c[         control char    (ESC)
        \N{name}    named Unicode character

    NOTE: 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 lowercase
        \u          rende il carattere successivo uppercase
        \L          rende lowercase fino a \E
        \U          rende uppercase fino \E
        \E          termina la modifica del case
        \Q          quota caratteri non-word fino a \E

    Se state usando use locale, la mappatura del case [?] usata da \l, \L, \u e \U è presa dal locale corrente. Si veda perllocale. Se Unicode (per esempio, \N{} o caratteri esadecimali più ampi di 0x100) è stato usato, la mappatura del case usata da \l, \L, \u e \U è come definita dall'Unicode. Per documentazione di \N{name}, si veda charnames.

    Tutti i sistemi utilizzano "\n" per rappresentare un terminatore di linea, chiamato ``newline'' (letteralmente ``nuova linea'' N.d.T). Non c'è qualcosa come un invariante, 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 emettere dati non veri. In generale, usate "\n" quando intendete un ``newline'' per il vostro sistema, ma usate un literal ASCII 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, potreste bruciarvi un giorno o l'altro.

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

    Interpolare un array o uno slice interpola gli elementi in ordine, separati dal valore di $", il che è equivalente ad interpolare join $", @array. Array ``Punctuation'' (NdT: array il cui nome e' costituito da segni di interpunzione) come @+ sono interpolati solamente se il nome è racchiuso in parentesi @{+}.

    Non potete includere un letterale come $ o @ all'interno di una sequenza \Q. Una sequenza non preceduta da un \ unescaped [?] $ o @ interpola la variabile corrispondente, mentre facendo precedere la sequenza da un \ causerà l'inserimento della stringa letterale \$. Avrete bisogno di 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 può essere incorporata nel pattern dalle variabili. Se non è questo che volete, usate \Q per interpolare una variabile letteralmente.

    A parte il comportamento descritto sopra, Perl non espande livelli multipli di interpolazione. In particolare, contrariamente alle aspettative dei programmatori di shell, il back-quote NON interpola all'interno di un doppio quote, e nemmeno i quote singoli impediscono la valutazione delle variabili quando usate all'interno di un doppio quote.[?] rivedere

    Operatori Quote-Like per Regexp

    Ecco gli operatori quote-like che si applicano al pattern matching e ad attivita correlate.

    ?PATTERN?
    Questo è come /pattern/, eccetto che trova una corrispondenza solo una volta tra le chiamate all'operatore reset(). Rappresenta una utile ottimizzazione quando volete vedere solo se la prima occorrenza di qualcosa in ciascun file o in un set di file, per esempio. Solo ?? i pattern locali al package corrente sono resettati. [?]
        while (<>) {
            if (?^$?) {
                                # linea vuota tra header e body
            }
        } continue {
            reset if eof;       # pulisce lo stato di ?? per il prossimo file
        }

    Questo utilizzo è vagamente deprecato, il che significa che potrebbe possibilmente esser rimosso in qualche versione futura molto lontana di Perl, forse da qualche parte intorno all'anno 2168.

    m/PATTERN/cgimosx
    /PATTERN/cgimosx Cerca una stringa per un pattern match, e in contesto scalare restituisce vero se la corrispondenza è trovata, altrimenti falso. Se nessuna stringa viene specificata attraverso l'operatore =~ o !~, la ricerca avviene nella variabile $_. (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 ricordate che =~ crea un legame piuttosto stretto.) Si veda anche perlre. Si veda perllocale per discussioni su considerazioni aggiuntive che scattano quando use locale è in uso.
    Le opzioni sono:
        c   Non resetta la posizione di ricerca in seguito ad un match fallito quando si sta utilizzando /g
        g   Fa match globalmente, i.e. trova tutte le occorrenze.
        i   Esegue un pattern match case insensitive.
        m   Tratta le stringhe come linee multiple.
        o   Compila il pattern solo una volta.
        s   Tratta la stringa come una singola linea.
        x   Usa espressioni regolari estese.

    Se ``/'' è il delimitatore allota la m iniziale è opzionale. Con m potete usare una coppia di caratteri non alfanumerici e 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 pendente, NdT]. Se ``?'' è il delimitatore, allora funziona la regola del match solo 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 verrà ricompilato) ogni volta che il pattern di ricerca sarà  valutato, tranne che quando il il delimitatore è un quote singolo. (Notate che $(, $), e $| non sono interpolati perché assomigliano a dei test di fine stringa.) Se volte che tali pattern siano compilati solo una volta, aggiungete un /o dopo il trailing delimitatore [?]. Questo aggira costose ricompilazioni a run-time, ed è utile quando il valore che state interpolando non cambierà  durante il tempo di vita del programma. Comunque, menzionando /o costituisce una promessa che non cambierete le variabili nel pattern. Se le cambiate, Perl non ve lo notificherà . Si veda anche qr/STRING/imosx.

    Se PATTERN valuta una stringa vuota, verrà utilizzata l'ultima espressione regolare valutata con successo. In questo caso, solo i flag g e c sul pattern vuoto is honoured [?] - gli altri flag sono presi dal pattern originale. Se non è avvenuto un match precedentemente, questo (silenziosamente) funzionerà  come un pattern vuoto genuino (che farà  match sempre).

    Se l'opzione /g non è utilizzata, m// in contesto lista restituisce una lista che consiste di sottoespressioni che hanno fatto match con le parentesi nel pattern, i.e., ($1, $2, $3...). (Notate che qyu $1 etc. sono anche settati, e che questo è diverso dal comportamento che si aveva in Perl 4.) Quando non ci sono parentesi nel pattern, il valore restituito è la lista (1) per successo [?]. Con o senza parentesi, viene restituita una lista vuota a seguito di un fallimento.

    Esempi:

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

    L'ultimo esempio divide $foo nelle prime due parole e nel rimanente della linea, ed assegna questi tre campi a $F1, $F2, ed $Etc. La condizione è vera se qualsiasi delle variabili fosse assegnata, i.e., se il pattern fa 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 lista, restituisce una lista delle sottostringhe che hanno fatto match, come se ci fossero parentesi intorno all'intero pattern.

    In contesto scalare, ciascuna esecuzione di m//g trova il prossimo match, restituendo vero se matcha, e falso se non ci sono ulteriori match. La posizione dopo l'ultimo match può esser letta o settata utilizzando la funzione pos(); si veda perlfunc/pos. Un match che fallisce normalmente resetta la search position [posizione di ricerca, NdT] all'inizio della stringa, ma lo potete evitare con l'aggiunta del modificatore /c (e.g. m//gc). Modificare la stringa target resetta anche la search position.

    Potete mescolare il match m//g con m/\G.../g, dove \G è un'asserzione zero-width [ampiezza zero, NdT] che matcha l'esatta posizione dove il precedente m//g aveva lasciato fuori [?]. Senza il moficiatore /g, l'asserzione \G si ancora ancora a pos(), ma il match è ovviamente tentato solamente una volta. Utilizzando \G senza /g su una stringa sulla quale non è stato applicato un match di tipo /g, equivle ad un'asserzione \A che matcha l'inzio della stringa. Notate anche che, attualmente, \G è supportato correttamente sono quando ancorato all'inzio di un pattern.

    Esempi:

        # list context
        ($one,$five,$fifteen) = (`uptime` =~ /(\d+\.\d+)/g);
        # scalar context
        $/ = "";
        while (defined($paragraph = <>)) {
            while ($paragraph =~ /[a-z]['")]*[.!?]+['")]*\s/g) {
                $sentences++;
            }
        }
        print "$sentences\n";
        # using m//gc with \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 "Final: '$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
        Final: 'q', pos=8

    Notate che l'ultimo match ha matchato q invece di p, lo stesso che un match senza l'ancora \G avrebbe fatto. Notate anche che l'ultimo match non ha aggiornato pos -- pos è aggiornato solamente su un match con /g. Se il match finale ha veramente matchato p, ci sarebbe da scommettere che state utillizzando un Perl più vecchio di pre-5.6.0.

    Un utile idioma a mo di legge [?]

     $_ = <<'EOL';
          $url = new URI::URL "http://www/";;   die if $url eq "xXx";
     EOL
     LOOP:
        {
          print(" digits"),         redo LOOP if /\G\d+\b[,.;]?\s*/gc;
          print(" lowercase"),      redo LOOP if /\G[a-z]+\b[,.;]?\s*/gc;
          print(" UPPERCASE"),      redo LOOP if /\G[A-Z]+\b[,.;]?\s*/gc;
          print(" Capitalized"),    redo LOOP if /\G[A-Z][a-z]+\b[,.;]?\s*/gc;
          print(" MiXeD"),          redo LOOP if /\G[A-Za-z]+\b[,.;]?\s*/gc;
          print(" alphanumeric"),   redo LOOP if /\G[A-Za-z0-9]+\b[,.;]?\s*/gc;
          print(" line-noise"),     redo LOOP if /\G[^A-Za-z0-9]+/gc;
          print ". That's all!\n";
        }

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

     line-noise lowercase line-noise lowercase UPPERCASE line-noise
     UPPERCASE line-noise lowercase line-noise lowercase line-noise
     lowercase lowercase line-noise lowercase lowercase line-noise
     MiXeD line-noise. That's all!

    q/STRING/
    'STRING'
    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.
        $foo = q!I said, "Tu dici, 'Lei lo dice.'"!;
        $bar = q('Questo E<egrave>.');
        $baz = '\n';        # una stringa di due caratteri

    qq/STRING/

    ``STRING''
    Un doppio quote, stringa interpolata.
        $_ .= qq
         (*** The previous line contains the naughty word "$1".\n)
                    if /\b(tcl|java|python)\b/i;      # :-)
        $baz = "\n";                # a one-character string

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

    Per esempio,

        $rex = qr/my.STRING/is;
        s/$rex/foo/;

    è equivalente a

        s/my.STRING/foo/is;

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

        $re = qr/$pattern/;
        $string =~ /foo${re}bar/;   # puE<ograve> esser interpolato in altri pattern
        $string =~ $re;             # oppure usato da solo
        $string =~ /$re/;           # o in questo modo

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

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

    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 sopra se non avessimo usato l'operatore qr().)

    Le opzioni sono:

        i   Do case-insensitive pattern matching.
        m   Treat string as multiple lines.
        o   Compile pattern only once.
        s   Treat string as single line.
        x   Use extended regular expressions.

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

    qx/STRING/
    `STRING`
    Una stringa che viene (possibilmente) interpolata e poi eseguita come un comando di sistema come /bin/sh o equivalente. Wildcard della shell, pipe e redirezioni saranno onorate (mantenute). L'outputo raccolto viene restituito; lo standard error no. In contesto scalare, ritorna come una singola stringa (potenzialmente multilinea), oppure undef se il comando fallisce. In contesto lista, restituisce una lista di linee (o comunque in base a come avete definito $/ o $INPUT_RECORD_SEPARATOR), o una lista stringa se il comando fallisce.

    Dato che il backtick non affligge lo standard error, usate la sintassi di shell per il descrittore di file (supponendo che la shell la supporti) se vi interessa questo. Per catturare lo STDERR e STDOUT di un comando insieme:

        $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 in maniera da catturare lo STDERR ma lasciare uscire STDOUT nel vecchio STDERR:

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

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

        system("program args 1>program.stdout 2>program.stderr");

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

        $perl_info  = qx(ps $$);            # $$
        $shell_info = qx'ps $$';            # che E<egrave> il $$ della nuova shell

    Come quella stringa venga valutata è 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 quali caratteri necessitano di essere escapizzati. Si veda perlsec per un esempio pulito e sicuro dal manuale di fork() ed exec() per emulare il backtick in sicurezza.

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

    A partire dalla v5.6.0, Perl cercerà di mandare in output tutti i file aperti prima di iniziare il processo figlio, ma questo potrebbe non esser supportato su alcune piattaforme (si veda perlport). Per esser sicuri, potreste aver bisogno di settare $| ($AUTOFLUSH in Inglese) o chiamare il metodo autoslush() di IO::Handle su qualsiasi handle aperto.

    Fate attenzione al fatto che alcuni comandi di shell potrebbero porre delle restrizioni sulla lughezza della linea di comando. Dovete assicurarvi che le vostre stringhe non eccadano questo limite dopo le necessarie interpolazioni. Si veda le note specifiche alla piattaforma utilizzata per ulteriori dettagli riguardo al vostro ambiente.

    Usare questo operatore può condurre a programmi che sono difficili da portare, dato che i comandi di shell chiamati variano tra i vari sistemi, e potrebbero infatti non esser presenti per niente. Come esempio, il comando type nelle shell POSIX è molto differente dal comando type del DOS. Questo non significa che dovreste uscire dalla vostra strada per aggirare i backtick quando essi sono il modo corretto di fare qualcosa. Perl fu fatto per essere un linguaggio glue [collante, NdT], e una delle cose che lui incolla insieme sono i comandi. Dovete solo capire in cosa vi state muovendo.

    Si veda I/O Operators per ulteriori discussioni.

    qw/STRING/
    Valuta una lista delle parole estratta da STRING, utilizzando uno spazio integrato come delimitatore di parole. Può esser compreso come essere rozzamente equivalente a:
        split(' ', q/STRING/);

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

        qw( foo bar baz )

    è semanticamente equivalente alla lista:

        'foo', 'bar', 'baz'

    Alcuni esempi visti di frequente:

        use POSIX qw( setlocale localeconv )
        @EXPORT = qw( foo bar baz );

    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 lo switch -w (cioè, la variabile $^W) produce degli avvertimenti se la STRING contiene ``,'' o il carattere ``#''.

    s/PATTERN/RIMPIAZZAMENTO/egimosx
    Cerca una stringa secondo un pattern, e se lo trova, rimpiazza quel pattern con il testo di rimpiazzamento e restituisce il numero di sostituzioni fatte. Altrimenti restituisce falso (in particolare, la stringa vuota).

    Se nessuna stringa viene specificata tramite l'operatore =~ o !~, la ricerca è fatta nella variabile $_ e poi questa viene modificata. (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, i.e., un lvalue.)

    Se il delimitatore scelto è un quote singolo, non viene fatta interpolazione nè su PATTERN o su REPLACEMENT. Altrimenti, se il PATTERN contiene un $ che assomiglia ad una variabile anzichè al test di fine stringa, la variabile sarà interpolata nel pattern a run-time. Se volete che il pattern venga compilato solo la prima volta che la variabile è interpolata, usate l'opzione /o. Se il pattern valuta una stringa vuota, verrà  utilizzata l'ultima espressione regolare eseguita con successo. Si veda perlre per ulteriori spiegazioni su questo argomento. Si veda perllocale per discussioni su considerazioni addizionali che funzionano quando use locale è in uso.

    Le opzioni sono:

        e   Valuta il lato destro di un'espressione.
        g   Rimpiazza globalmente, i.e., tutte le occorrenze.
        i   Esegue un pattern matching case-insensitive.
        m   Tratta la stringa come linee multiple.
        o   Compila il pattern solo una volta.
        s   Tratta la stringa come una linea singola.
        x   Usa espressioni regolari estese.

    Qualsiasi delimitatore non-alfanumerico o che non sia uno spazio potrebbe rimpiazzare lo slash. Se un singolo quote viene utilizzato, non viene fatta un'interpretazione sulla stringa di rimpiazzamento (il modificatore /e sovrascrive questo comportamento, comunque). Diversamente da Perl 4, Perl 5 tratta i backtick come dei normali delimitatori; il testo di rimpiazzamento non viene valutato come un comando. Se il PATTERN è delimitato da quote con parentesi, il RIMPIAZZAMENTO ha la sua personale coppia di quote, che potrebbe essere o no una coppia di parentesi, e.g., s(foo)(bar) oppure s<foo>/bar/. Un /e causerà che la porzione di rimpiazzamento venga trattata come una full-fledged espressione Perl e valutata correttamente e lì [?]. Comunque, la sintassi viene controllata a tempo di compilazione. Un secondo modificatore e causerà  un eval sulla porzione di rimpiazzamento prima di esser fatta girare come espressione Perl.

    Esempi:

        s/\bgreen\b/mauve/g;                # don't change wintergreen
        $path =~ s|/usr/bin|/usr/local/bin|;
        s/Login: $foo/Login: $bar/; # run-time pattern
        ($foo = $bar) =~ s/this/that/;      # copy first, then change
        $count = ($paragraph =~ s/Mister\b/Mr./g);  # get change-count
        $_ = 'abc123xyz';
        s/\d+/$&*2/e;               # yields 'abc246xyz'
        s/\d+/sprintf("%5d",$&)/e;  # yields 'abc  246xyz'
        s/\w/$& x 2/eg;             # yields 'aabbcc  224466xxyyzz'
        s/%(.)/$percent{$1}/g;      # change percent escapes; no /e
        s/%(.)/$percent{$1} || $&/ge;       # expr now, so /e
        s/^=(\w+)/&pod($1)/ge;      # use function call
        # expand variables in $_, but dynamics only, using
        # symbolic dereferencing
        s/\$(\w+)/${$1}/g;
        # Add one to the value of any numbers in the string
        s/(\d+)/1 + $1/eg;
        # This will expand any embedded scalar variable
        # (including lexicals) in $_ : First $1 is interpolated
        # to the variable name, and then evaluated
        s/(\$\w+)/$1/eeg;
        # Delete (most) C comments.
        $program =~ s {
            /\*     # Match the opening delimiter.
            .*?     # Match a minimal number of characters.
            \*/     # Match the closing delimiter.
        } []gsx;
        s/^\s*(.*?)\s*$/$1/;        # trim whitespace in $_, expensively
        for ($variable) {           # trim whitespace in $variable, cheap
            s/^\s+//;
            s/\s+$//;
        }
        s/([^ ]*) *([^ ]*)/$2 $1/;  # reverse 1st two fields

    Notate l'utilizzo di $ invece di \ nell'ultimo esempio. Diversamente da sed, noi usiamo il \digit solamente sul lato sinistro. Da qualsiasi altra parte esso è $<digit>.

    Occasionalmente, non potete usare solo un /g per ottenere tutti i cambi che potreste desiderare. Ecco due esempi comuni:

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

    tr/SEARCHLIST/RIMPIAZZAMENTO/cds
    y/SEARCHLIST/RIMPIAZZAMENTO/cds Traslittera tutte le occorrenze dei caratteri trovati nella lista di ricerca con i corrispondenti caratteri nella lista di rimpiazzamento. Restituisce il numero di caratteri rimpiazzati o cancellati. Se non specificate 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, i.e., a lvalue.)
    Un insieme di caratteri può esser specificato tramite un hyphen [trattino - , N.d.T.], quindi tr/A-J/0-9/ effettua lo stesso rimpiazzamento di tr/ACEGIBDFHJ/0246813579/. Per i devoti di sed, è possibile usare y come sinonimo di tr. Se la lista di ricerca è delimitata da quote con parentesi, la lista di rimpiazzamento avrà  la sua personale coppia di quote, che potrebbero essere o no delle parentesi, e.g., tr[A-Z][a-z] o tr(+\-*/)/ABCD/.

    Notate che tr non esegue classi di caratteri di espressioni regolari come \d o [:lower:] [?]. L'operatore tr non è equivalente all'utility tr(1). Se volete mappare stringhe lower/upper case, si veda perlfunc/lc e perlfunc/uc, ed in generale considerate di utilizzare l'operatore s se avete bisogno delle espressioni regolari.

    Notate anche che l'idea di insieme 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. Così ad orecchio è buona norma utilizzare degli insiemi di caratteri che iniziano e finiscono alfabeticamemente con lo stesso case (minuscolo: a-e, maiuscolo: A-E), oppure numeri (0-4). Tutto il resto non è sicuro. Nel dubbio, specificate interamente tutto il set di caratteri.

    Options:

        c   Complementa la lista di RICERCA.
        d   Cancella i caratteri trovati ma non rimpiazzati.
        s   Toglie i caratteri duplicati rimpiazzati.

    Se specificate il modificatore /c, il set di caratteri della lista di RICERCA viene complementata. Se è specificato il modificatore /d, qualsiasi carattere specificato nella lista di RICERCA non trovato nella lista di RIMPIAZZAMENTO viene cancellato. (Notate che questo è leggermente più flessibile del funzionamento di alcuni programmi tr, i quali cancellano qualsiasi cosa essi trovino nella lista di RICERCA.) Se il modificatore /s viene specificato, le sequenze di caratteri che sarebbero traslitterate allo stesso carattere, vengono ridotte ad una singola istanza di quel carattere.

    Se viene usato il modificatore /d, la lista di RIMPIAZZAMENTO viene sempre interpretata come specificato. Altrimenti, se la lista di RIMPIAZZAMENTO è più corta della lista di RICERCA, il carattere finale viene replicato quanto basta. Se la lista di RIMPIAZZAMENTO è vuota, la lista di RICERCA viene replicata. L'ultima cosa è utile per contare i caratteri in una classe o per cancellare sequenze di caratteri in una classe.

    Examples:

        $ARGV[1] =~ tr/A-Z/a-z/;    # porta tutto in minuscolo
        $cnt = tr/*/*/;             # counta le stelle in $_
        $cnt = $cielo =~ tr/*/*/;   # counta le stelle nel $cielo
        $cnt = tr/0-9//;            # counta i numeri in $_
        tr/a-zA-Z//s;               # bookkeeper -> bokeper
        ($HOST = $host) =~ tr/a-z/A-Z/;
        tr/a-zA-Z/ /cs;             # cambia i caratteri non alfabetici in spazi
        tr [\200-\377]
           [\000-\177];             # cancella l'ottavo bit

    Se vengono date più traslitterazioni per un carattere, solo il primo viene utilizzato:

        tr/AAA/XYZ/

    traslittera qualunque A con una X.

    Dato che la tabella di traslitterazione viene costruita a tempo di compilazione, nè la lista di RICERCA, nè la lista di RIMPIAZZAMENTO sono soggetti ad interpolazione con il doppio quote. Il che vuol dire che se usate una variabile, dovete passare per 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''. A seguito di un <<, specificate una stringa che termina la roba quotata, e tutte le linee che seguono quella corrente fino alla stringa che termina costituiscono il valore di quell'item [elemento, N.d.T.]. La stringa che termina potrebbe esser sia un identificatore (una parola), o del testo quotato. Se quotato, il tipo di quote che utilizzate determina il trattamento del testo, come nel quote normale. Un identificatore non quotato funziona come un quote doppio. Non ci devono essere spazi tra << e l'identificatore, se l'identificatore non è quotato. (Se mettete uno spazio, sarà  trattato come identificatore nullo, che è valido, e matcha la prima linea vuota.) La stringa che termina deve esser presente (non quotata e senza spazi intorno) sulla linea che termina
           print <<EOF;
        Il prezzo E<egrave> $Prezzo.
        EOF
           print << "EOF"; # lo stesso come sopra
        Il prezzo E<egrave> $Prezzo.
        EOF
           print << `EOC`; # esegue i comandi
        echo alto
        echo basso
        EOC
           print <<"foo", <<"bar"; # potete raggrupparli
        Ho detto foo.
        foo
        Ho detto bar.
        bar
           myfunc(<< "THIS", 23, <<'THAT');
        Qui c'E<egrave> una linea
        o due.
        THIS
        e qui un'altra.
        THAT

    Non vi dimenticate che dovete mettere un punto e virgola alla fine dell'istruzione, Perl non sa che non proverete a fare questo:

           print <<ABC
        179231
        ABC
           + 20;

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

        ($quote = <<'FINIS') =~ s/^\s+//gm;
           The Road goes ever on and on, 
           down from the door where it began.
        FINIS

    Se usate here-doc all'interno di un costrutto delimitato, come in s///eg, la roba quotata deve andate tutta dentro il delimitatore finale Quindi invece di

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

    dovete scrivere

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

    Se l'identificatore che termina è sull'ultima linea del programma, dovete assicurarvi che ci sia un a capo dopo di esso; altrimenti, Perl vi darà  un avvertimento Can't find string terminator ``END'' anywhere before EOF....

    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 possibile è per fare backslash del carattere di quote:

        print << "abc\"def";
        testing...
        abc"def

    Per chiudere, le stringhe quotate non possono stare su linee multiple. La regola generale è che l'identificatore deve essere una stringa letterale. Attenetevi a questa e dovreste esser al sicuro.

    Sanguinolenti dettagli sui costrutti di parsing quotati

    Quando viene presentato con qualcosa che potrebbe avere svariate interpretazioni, Perl utilizza il principio DWIM (cioè ``Do What I Mean'') [Fai quello che intendo, N.d.T.] per azzeccare l'interpretazione più probabile. Questa strategia è cosଠvincente che spesso i programmatori Perl non sospettano nulla riguardo l'ambivalenza di ciಠche scrivono. Ma da un momento all'altro, le fantasie del Perl differiscono sostanzialmente da quello che l'autore onestamente intendeva.

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

    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 capite questa regola, potreste saltare il resto della sezione ad una prima lettura.

    Alcuni passi discussi successivamente sono eseguiti concorrentemente, ma dato che i loro risultati sono gli stessi, li consideriamo individualmente. Per costrutti di quoting differenti, Perl esegue un differente numero di passi, da uno a cinque, ma questi passi sono sempre eseguiti nello stesso ordine.

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

    Quando si cerca per delimitatori a singolo carattere non accoppiati, come /, combinazioni di \\ e \/ vengono saltate. Comunque, quando si cerca per un delimitatore a singolo carattere accoppiato come [, le combinazioni di \\, \], e \[ sono tutte saltate, e i [, ] innestati sono anch'essi saltati. Quando si cerca per delimitatori multicarattere, niente viene saltato.

    Per costrutti con delimitatori a 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{"$foo/$bar"}"

    o:

        m/ 
          bar       # NON 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 un SPACE, 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\/ è interpretato come una parte di \/, e il seguente / non è riconosciuto come delimitatore. Invece, usate \034 o \x1c alla fine del costrutto quotato.

    Rimozione del backslash prima dei delimitatori
    Durante il secondo passaggio, il testo tra il delimitatore iniziale e finale è copiato in una locazione sicura, il \ è rimosso dalle combinazioni che consistono di \ e il delimitatore--o i delimitatori, cioè entrambi i delimitatori di inizio e di fineiniziano e [?] Questa rimozione non accade per delimitatori multicarattere. Notate la combinazione \\ è intatta a sinistra, giusto come era.

    Da questo passo, 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///
    Nessuna interpolazione viene effettuata.

    '', 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 costrutto Perl corrispondente. Quindi, "$foo\Qbaz$bar" viene convertito a $foo . (quotemeta("baz" . $bar)) internamente. Le altre combinazioni sono rimpiazzate con espansioni appropriate.

    Ripetiamo che qualsiasi cosa tra \Q e \E viene interpolata alla stessa maniera. Qualcosa come "\Q\\E" non ha \E dentro. Invece, ha \Q, \\, e E, cosଠche il risultato è lo stesso che per "\\\\E". Come regola generale, backslashes tra \Q e \E potrebbero portare a risultati contro intuitivi. Cosà¬, "\Q\t\E" è convertito a quotemeta("\t"), il quale è lo stesso come "\\\t" (dato che TAB non è alfanumerico). Notate anche che:

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

    potrebbe esser molto vicina all' intenzione congetturale dello scrittore di "\Q\t\E".

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

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

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

    Dato che il risultato di "\Q STRING \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 e diventa "\\\$"; se no, viene interpretato come l'inizio di uno scalare interpolato.

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

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

    oppure:

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

    Il più delle volte, il codice più lungo possibile che non include spazi tra i componenti e che contiene parentesi di match o quadre, dato che l'esito puಠessere determinato in base ad un voto euristico degli estimatori, il risultato non è strettamente predicibile. Fortunatamente, è di solito corretto per casi ambigui.

    ?RE?, /RE/, m/RE/, s/RE/foo/,
    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 RE (incluso \) non viene eseguita. Inoltre, dentro un (?{BLOCK}), (?# comment ), e un commento # in una espressione regolare con //x, non viene eseguita alcuna elaborazione. Questo è il primo passo nel quale la presenza del modificatore //x è rilevante.

    L'interpolazione ha diverse stranezze: $|, $(, e $) non vengono interpolati, e i costrutti $var[SOMETHING] son votati (da estimatori differenti) ad essere o un elemento di un array o un $var seguito da una RE alternativa. Questo è il caso nel quale la notazione ${arr[$bar]} diventa funzionale: /${arr[0-9]}/ è interpretata come l'elemento dell'array -9, non come un'espressione regolare dalla variabile $arr seguita da un numero, che sarebbe l'interpretazione di /$arr[0-9]/. Dato che potrebbe accadere una votazione tra differenti estimatori, il risultato non è predicibile.

    È a questo punto che \1 viene convertito a malincuore a $1 nel testo di rimpiazzo di s/// per correggere gli incorregibili sed hacker che non hanno ancora fatto loro l'idioma giusto. Un avvertimento viene emesso se la direttiva use warnings o il flag -w sulla linea di comando (cioè, la variabile $^W) era settato.

    La mancanza di elaborazione di \\ crea delle specifiche restrizioni sul testo post-processato. Se il delimitatore è /, uno non può avere la combinazione \/ nel risulato di questo step. / terminer&agreve; l'espressione regolare, \/ sarà ripulita in / nello step precedente, e \\/ verrà lasciato come è. Dato che / è equivalente a \/ dentro ad un'espressione regolare, questo non importa se il delimitatore non è un carattere speciale per il motore RE, come in s*foo*bar*, m[foo], o ?foo?; o un carattere alfanumerico, come in:

      m m ^ a \s* b mmx;

    Nella RE 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 una ragione che vi ha incoraggiato a restringere i vostri delimitatori a scelte non-alfanumeriche e con senza spazi vuoti.

    Questo passo è l'ultimo per tutti i costrutti tranne che 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 potrebbe esser ottimizzato ad esser calcolato a tempo di compilazione se opportuno. Dopo la pre-elaborazione descritta sopra, e possibilmente dopo la valutazione se sono coinvolti concatenazione, unione, traduzione dei case [delimitatori, N.d.T.], o il mataquoting, la stringa risultante viene passata al motore RE per la compilazione.

    Qualunque cosa accada nel motore RE potrebbe esser discusso meglio in perlre, ma per ragioni di continuità, dobbiamo farlo anche qui.

    Questo è un altro passo nel quale la presenza del modificatore //x è rilevante. Il motore RE scansiona la stringa da sinistra a destra e la converte in un automa finito.

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

    Il parsing del costrutto a parentesi quadre, è piuttosto differente rispetto alle regole utilizzate per il resto del pattern. Il terminatore di questo costrutto viene trovato utilizzando le stesse regole come per trovare il terminatore di un costrutto delimitato da {}, l'unica eccezione è ] che essendo immediatamente seguito da [ viene trattato come preceduto da un backslash. In maniera simile, il terminatore (?{...}) viene trovato usando le stesse regole come per trovare il terminatore di un costrutto delimitato da {}.

    È possibile ispezionare sia la stringa data al motore RE che l'automa finito risultante. Vedere gli argomenti debug/debugcolor nella direttiva use re, così come per lo switch -Dr sulla linea di comando di Perl in perlrun/``Command Switches''.

    Ottimizzazioni delle espressioni regolari
    Questo passo è elencato solo per completezza. Dato che esso non cambia le semantiche, i dettagli di questo passo non sono documentati e sono soggetti a cambiamenti senza notifica. Questo passo viene eseguito dopo che l'automa finito era generato durante il passo precedente.

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

    Operatori di I/O >>

    Ci sono diversi operatori di I/O dei quali dovreste sapere qualcosa.

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

    In contesto scalare, valutare un filehandle in 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 $/ è settato ad undef (a volte conosciuto come modalità file-slurp) e il file è vuoto, esso ritorno '' la prima volta, seguito successivamente da un undef.

    Di solito dovete assegnare il valore restituito ad una variabile, ma c'è una situazione nella quale accade un assegnamento automatico. Se e solo se il simbolo in input è la sola cosa dentro la condizione di un while (anche se travestito da for(;;)), il valore viene automaticamente assegnato alla variabile globale $_, distruggento qualsiasi cosa fosse lì precedentemente. (Questa vi potrebbe sembrare una cosa strana, ma userete questo costrutto in quasi tutti gli script Perl che scriverete). La variabile $_ non viene localizzata implicitamente. Dovrete mettere un local $_; prima del ciclo se volete che accada.

    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>;

    Questo anche si comporta in maniera simile, ma aggira $_ :

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

    In questi costrutti ciclici, il valore assegnato (se l'assegnamento è automatico o esplicito) viene testato per vedere se esso è definito. Il test defined aggira 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. Se veramente volete terminare il ciclo per quei valori allora dovrete testarli esplicitamente:

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

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

    
    I filehandle STDIN, STDOUT, e STDERR sono predefiniti. (I filehandle
    C<stdin>, C<stdout>, e C<stderr> funzioneranno anche eccetto che nei
    package, dove verrebbero interpretati come identificatori locali
    anzichE<egrave> globali). Dei filehandle addizionai possono esser creati
    con la funzione open(), tra le altre cose. Si veda L<perlopentut> e 
    L<perlfunc/open> per dettagli su questo.
    X<stdin> X<stdout> X<sterr>

    Se un <FILEHANDLE> è usato in un contesto che sta cercando per una lista, viene restituita una lista comprendente tutte le linee di input, una linea per ciascun elemento della lista. È facile crescere ed ottenere un insieme di dati molto grande in questo modo, 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 listato sulla linea di comando. Ecco come funziona: la prima volta che <> viene valutato, l'array @ARGV viene controllato, e se è vuoto, $ARGV[0] viene settato a ``-'', cosଠche quando viene aperto, vi da 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>) {
                ...         # code for each line
            }
        }

    eccetto il fatto che non è cosଠscomodo da scrivere, e funziona veramente. Esegue davvero lo shift sull'array @ARGV e mette il nome di 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.)

    Potete modificare @ARGV prima del primo <> affinchè l'array finisca col contenere la lista dei nomi di file che volete veramente. I numeri di linea ($.) continuano a crescere file dopo file anche se l'input fosse un file molto grande. Si veda l'esempio in perlfunc/eof per capire come resettare i numeri di linea in ogni file.

    Se volete settare @ARGV alla vostra lista di file, modificatelo in anticipo. Questo inserisce in @ARGV tutti file di testo con codifica ASCII se non viene dato @ARGV:

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

    Potete anche settarli ad una pipe di comandi. Per esempio, questo filtra automaticamente i file compressi, passati come argomento, tramite gzip:

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

    Se volete passare degli switch (le opzioni da riga di comando come --verbose, N.d.T.) ai vostri script, potete utilizzare uno dei moduli Getopt o inserire davanti un ciclo come questo:

        while ($_ = $ARGV[0], /^-/) {
            shift;
            last if /^--$/;
            if (/^-D(.*)/) { $debug = $1 }
            if (/^-v/)     { $verbose++  }
            # ...           # other switches
        }
        while (<>) {
            # ...           # code for each line
        }

    Il simbolo <> restituirà  undef alla fine del file solo una volta. Se lo chiamate ancora una volta dopo di questo, esso assumerà  che stiate processando un'altro array @ARGV, e se non avete settato @ARGV, leggerà  l'input da STDIN.

    Se quello che le parentesi angolari contengono è semplicemente una variabile scalare (per esempio, <$foo>), 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;
        $line = <$fh>;

    Se quello 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 da esser espanso, e o una lista di nomi di file o il prossimo nome di file nella lista viene restituito, a seconda del contesto. Questa distinzione è determinata su base sintattica. Cioè <$x> è sempre una readline() da un handle indiretto, ma <$hash{key}> è sempre un glob(). Questo perché $x è una semplice variabile scalare, ma $hash{key} no--è un elemento di hash. Anche <$x > (notate lo spazio extra) è trattato come glob("$x "), non come readline($x).

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

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

    è equivalente all'incirca a:

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

    eccetto che il glob viene fatto internamente utilizzando l'estensione standard File::Glob. Naturalmente, la via più corte per fare quanto sopra è:

        chmod 0644, <*.c>;

    Un (file)glob valuta il suo argomento (interno) solo quando sta iniziando una nuova lista. Tutti i valori devono esser letti prima che inizi un'altra volta. In contesto lista, questo non è importamente perché li ottenete comunque tutti. Tuttavia, in contesto scalare l'operatore restituisce il prossimo valore ogni volta che viene chiamato, oppure undef quando la lista è finita. Come con la lettura dei filehandle, viene generato un automatico defined quando il glob capita 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 solo una volta. Cosଠse vi state aspettando un solo valore da un glob, è molto meglio dire

        ($file) = <blurch*>;

    che

        $file = <blurch*>;

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

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

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

    Folding Costante

    Come il C, Perl esegue un certo numero 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 dei letterali che non fanno una sostituzione variabile. Anche l'interpolazione del backslash avviene a tempo di compilazione, Potete dire

        'Ora E<egrave> il momento per tutte' . "\n" .
            'le brave persone di venire a.'

    e tutto questo si riduce ad una stringa internamente. Allo stesso modo, se dite

        foreach $file (@filenames) {
            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.

    No-ops

    Perl non ha ufficialmente un operatore no-op, ma le semplici costanti 0 e 1 sono casi speciali che non producono degli avvertimenti in constesto void (vuoto, N.d.T.), cosଠche potete fare in modo sicuro

        1 while foo();

    Operatori di bit su stringhe

    Stringhe di bit di qualunque dimensione possono esser manipolati dagli operatori di bit su stringhe (~ | & ^).

    Se gli operandi di un operatori di bit binario sono delle stringhe di dimensioni differenti, gli operatori | e ^ funzionano come se l'operando più corto avesse dei bit settati 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 è uno o più byte.

        # esempio basato su ASCII 
        print "j p \n" ^ " a h";            # stampa "JAPH\n"
        print "JA" | "  ph\n";              # stampa "japh\n"
        print "japh\nJunk" & '_____';       # stampa "JAPH\n";
        print 'p N$' ^ " E<H\n";            # stampa "Perl\n";

    Se state intendendo che volete manipolare stringhe di bit, siate certi che state fornendo stringhe di bit: se un operando è un numero, ciಠimplicherà  una operazione di bit numerica. Potreste esplicitamente mostrare che tipo di operazione intendete utilizzando "" o 0+, come nell'esempio qui sotto.

        $foo =  150  |  105;        # produce 255  (0x96 | 0x69 E<egrave> 0xFF)
        $foo = '150' |  105;        # produce 255
        $foo =  150  | '105';       # produce 255
        $foo = '150' | '105';       # produce la stringa '155' (sotto ASCII)
        $baz = 0+$foo & 0+$bar;     # entrambi gli opearndi sono esplicitamente numerici
        $biz = "$foo" ^ "$bar";     # entrambi gli opearndi sono esplicitamente delle stringhe

    Si veda perlfunc/vec per informazioni su come manipolare bit singoli in un vettore di bit.

    Aritmetica intera

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

        use integer;

    potete dire al compilatore che va bene utilizzare le operazioni intere (se se la sente) da qui alla fine del BLOCK. Un blocco innestato potrebbe revocare ciಠdicendo

        no integer;

    che dura fino alla fine di quel BLOCK. Notate che questo non vuol dire che tutto è solamente un intero, meramente 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 simili.

    Usato sui numeri, gli operatori sui bit (``&'', ``|'', ``^'', ``~'', ``<<'', e ``>>'') producono sempre risultati interi. (Ma date un'occhiata anche Operatori di bit su stringhe.) Comunque, use integer ha ancora senso per essi. Di default, i loro risultati sono interpretati come interi senza segno, ma se use integer è in azione, i loro risultati sono interpretati come interi con segno. Per esempio, ~0 solitamente fa una valutazione ad un valore intero grande. Tuttavia, use integer; ~0 è -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 arrotondamento automatico o troncamento a 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;
        #        produces 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 un particolare numero di cifre decimali. Si veda Knuth, volume II, per un trattamento più robusto di questo argomento.

        sub fp_equal {
            my ($X, $Y, $POINTS) = @_;
            my ($tX, $tY);
            $tX = sprintf("%.${POINTS}g", $X);
            $tY = sprintf("%.${POINTS}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 esser specificato precisamente. In questi casi, esso paga il fatto di non fidarsi di qualsiasi sistema di arrotondamento venga utilizzato dal Perl, ma invece di implementare la funzione di arrotondamento di c [?] -_-

    Numeri più grandi

    I moduli standard Math::BigInt and Math::BigFloat forniscono operatori aritmetici a precisione variabile operatori overloaded operatori, sebbene attualmente sono 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;
        # prints +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 corto, 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 vettori di bit velocemente (usa il C)
            Math::BigIntFast        e` un wrapper a Bit::Vector per numeri grandi 
            Math::Pari              fornisce accesso alla libreria Pari C
            Math::BigInteger        usa una libreria C esterna
            Math::Cephes            usa la libreria Cephes C (non per numeri grandi)
            Math::Cephes::Fraction  frazioni attraverso la libreria Cephes
            Math::GMP               un altro che usa una libreria C esterna

    Scegliete 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 .


    Wed Jan 28 14:17:56 2009