Successivo: Contributori, Precedente: Estensioni comuni, Su: Storia del linguaggio [Contenuti][Indice]
Questa
sezione descrive la storia confusionaria degli intervalli
all’interno di espressioni regolari, le loro relazioni con la localizzazione,
e l’effetto da ciò determinato su diverse versioni di gawk
.
Gli strumenti originali Unix aventi a che fare con espressioni regolari stabilivano che intervalli di caratteri (come ‘[a-z]’) individuavano un carattere qualsiasi tra il primo carattere dell’intervallo e l’ultimo carattere dello stesso, entrambi inclusi. L’ordinamento era basato sul valore numerico di ogni carattere come era rappresentato all’interno del computer, nell’insieme di caratteri proprio di ogni macchina. Quindi, su sistemi che adottano la codifica ASCII, ‘[a-z]’ individua tutte le lettere minuscole, e solo quelle, in quanto i valori numerici che rappresentano le lettere dalla ‘a’ fino alla ‘z’ sono contigui. (In un sistema che adotta la codifica EBCDIC, l’intervallo ‘[a-z]’ comprende anche ulteriori caratteri non alfabetici.)
Quasi tutti i testi di introduzione allo Unix spiegavano che le espressioni di intervallo funzionavano in questo modo, e in particolare insegnavano che la maniera “corretta” per individuare le lettere minuscole era con ‘[a-z]’ e che ‘[A-Z]’ era il modo “corretto” per individuare le lettere maiuscole. E, in effetti, era proprio così.118
Lo standard POSIX 1992 introduceva l’idea di localizzazione (vedi la sezione Il luogo fa la differenza). Poiché molte localizzazioni comprendono altre lettere, oltre alle 26 lettere dell’alfabeto inglese, lo standard POSIX introduceva le classi di carattere (vedi la sezione Usare espressioni tra parentesi quadre) per permettere l’individuazione di differenti insiemi di caratteri, in aggiunta a quelli tradizionali presenti nell’insieme di caratteri ASCII.
Tuttavia, lo standard ha modificato l’interpretazione delle
espressioni di intervallo.
Nelle localizzazioni "C"
e "POSIX"
,
un’espressione di intervallo come
‘[a-dx-z]’ è ancora equivalente a ‘[abcdxyz]’, secondo l’ordine
della codifica ASCII.
Ma in tutte le altre localizzazioni l’ordinamento è basato su quel che
si chiama ordine di collazione.
Cosa vuol dire? In molte localizzazioni, le lettere ‘A’ e ‘a’ vengono entrambe prima di ‘B’. In altre parole, queste localizzazioni ordinano i caratteri nel modo in cui sono ordinati in un dizionario, e ‘[a-dx-z]’ non è detto che equivalga a ‘[abcdxyz]’; invece, potrebbe essere equivalente a ‘[ABCXYabcdxyz]’, per fare un esempio.
Su questo punto è opportuno insistere: molta documentazione afferma che si dovrebbe usare ‘[a-z]’ per identificare un carattere minuscolo. Ma su sistemi con localizzazioni non-ASCII, un tale intervallo potrebbe includere tutti i caratteri maiuscoli tranne ‘A’ o ‘Z’! Questo ha continuato a essere una fonte di equivoci perfino nel ventunesimo secolo.
Per dare un’idea del tipo di problemi, l’esempio seguente usa la funzione
sub()
, che effettua una sostituzione di testo all’interno di una
stringa (vedi la sezione Funzioni di manipolazione di stringhe). Qui, l’idea è quella di rimuovere
i caratteri maiuscoli a fine stringa:
$ echo qualcosa1234abc | gawk-3.1.8 '{ sub("[A-Z]*$", ""); print }' -| qualcosa1234a
Questo non è l’output che ci si aspettava, perché, il ‘bc’ alla fine di ‘qualcosa1234abc’ non dovrebbe essere individuato da ‘[A-Z]*’. Un tale risultato dipende dalle impostazioni di localizzazione (e quindi potrebbe non succedere sul sistema che si sta usando).
Considerazioni simili valgono per altri intervalli. Per esempio, ‘["-/]’
è perfettamente valido in ASCII, ma non è valido in molte localizzazioni
Unicode, p.es. in en_US.UTF-8
.
Il codice delle prime versioni di gawk
per individuare le
regexp non teneva conto della localizzazione, e quindi gli
intervalli potevano essere interpretati in maniera tradizionale.
Quando gawk
ha iniziato a usare metodi di ricerca di regexp
che tengono conto della localizzazione, sono iniziati i problemi;
a maggior ragione in quanto sia GNU/Linux che i venditori di versioni
commerciali di Unix
avevano iniziato a implementare localizzazioni non-ASCII,
adottandole per default. La domanda che forse si udiva più spesso
era del tipo: “Perché ‘[A-Z]’ individua lettere minuscole?!?”
Questa situazione è in essere da circa 10 anni, se non di più, e
il manutentore di gawk
si è stufato di continuare a spiegare che
gawk
stava semplicemente implementando quelli che sono gli
standard, e che il problema stava nella localizzazione dell’utente. Nella
fase di sviluppo della versione 4.0, gawk
è stato modificato
in modo da trattare sempre gli
intervalli "come si faceva prima di POSIX", a meno che non si specifichi
l’opzione --posix (vedi la sezione Opzioni sulla riga di comando).119
Fortunatamente, un po’ prima del rilascio definitivo della versione 4.0 di
gawk
, il manutentore ha appreso che lo standard 2008 aveva
modificato la definizione di intervallo, e che, al di fuori delle
localizzazioni "C"
e "POSIX"
, il significato di espressione
di intervallo era ora
indefinito.120
Adottando questo simpatico termine tecnico, lo standard permette agli
implementatori di implementare gli intervalli nella maniera che preferiscono.
Il manutentore di gawk
ha deciso di implementare la regola pre-POSIX
sia per l’individuazione di default delle regexp sia quando si
specificano le opzioni --traditional o --posix.
In ogni caso gawk
aderisce allo standard POSIX.
E la vita era semplice.
Ed è così che è nata la Campagna per l’Interpretazione Razionale degli Intervalli (in inglese, RRI [Rational Range Interpretation]). Un certo numero di strumenti GNU hanno già implementato questa modifica, o lo faranno presto. Grazie a Karl Berry per aver coniato la frase “Rational Range Interpretation”.
Si veda lo standard e le motivazioni.
Successivo: Contributori, Precedente: Estensioni comuni, Su: Storia del linguaggio [Contenuti][Indice]