PERL_UNICODE

Le
Benoit Izac
Bonjour,

Je suis passé récemment à UTF-8. En passant un nom de fichier avec un
accent à un petit script Perl, je me suis aperçu que lc() ne
fonctionnait pas sur ce caractère accentué. J'ai fini par trouver
l'option « -C » et la variable d'environnement PERL_UNICODE.

Sachant que j'ai encore pas mal de fichiers dans mon répertoire qui sont
en ISO-8859-1(5), quelles peuvent-être les conséquences d'exporter
PERL_UNICODE=SDA :
- pour mon shell interactif ?
- dans l'environnement global de ma machine (pour tous les
programmes) ?

Question subsidiaire : pourquoi ceci (-C L) ne fonctionne pas ?

% perl -e 'print "$]"'
5.008008
% locale
LANG=
LC_CTYPE=fr_FR.utf8
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=
% printf 'élève' | PERL_UNICODE=S perl -ne 'print uc'
ÉLÈVE
% printf 'élève' | PERL_UNICODE=L perl -ne 'print uc'
éLèVE

--
Benoit Izac
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Paul Gaborit
Le #19451581
À (at) Wed, 27 May 2009 22:17:46 +0200,
Benoit Izac
Je suis passé récemment à UTF-8. En passant un nom de fichier avec un
accent à un petit script Perl, je me suis aperçu que lc() ne
fonctionnait pas sur ce caractère accentué. J'ai fini par trouver
l'option « -C » et la variable d'environnement PERL_UNICODE.




Sans '-C' ni PERL_UNICODE, l'utilisation du module 'locale' doit
permettre de résoudre ce problème.

--
Paul Gaborit - Perl en français -
Benoit Izac
Le #19452401
Bonjour,

le 30/05/2009 à 19:30, Paul Gaborit a écrit dans le message

Je suis passé récemment à UTF-8. En passant un nom de fichier avec un
accent à un petit script Perl, je me suis aperçu que lc() ne
fonctionnait pas sur ce caractère accentué. J'ai fini par trouver
l'option « -C » et la variable d'environnement PERL_UNICODE.




Sans '-C' ni PERL_UNICODE, l'utilisation du module 'locale' doit
permettre de résoudre ce problème.



Non, c'est justement pour cela que je suis arrivé à PERL_UNICODE.

% printf 'élèven' | perl -ne 'use locale; print uc'
éLèVE

--
Benoit Izac
Nicolas George
Le #19453011
Benoit Izac wrote in message
% printf 'élèven' | perl -ne 'use locale; print uc'
éLèVE



Chez moi ça marche. Tes locales sont probablement mal configurées.

Ceci dit, use locale est bâti sur une API bancale, donc il vaudrait mieux ne
pas l'utiliser.
Paul Gaborit
Le #19454421
À (at) 30 May 2009 22:10:26 GMT,
Nicolas George
Benoit Izac wrote in message
% printf 'élèven' | perl -ne 'use locale; print uc'
éLèVE



Chez moi ça marche. Tes locales sont probablement mal configurées.

Ceci dit, use locale est bâti sur une API bancale, donc il vaudrait mieux ne
pas l'utiliser.



L'API est bancale mais la solution PERL_UNICODE me semble l'être
encore plus.

Je pense que la réglage correct des locales est absolument
nécessaire...

--
Paul Gaborit - Perl en français -
Benoit Izac
Le #19454511
Bonjour,

le 31/05/2009 à 00:10, Nicolas George a écrit dans le message

% printf 'élèven' | perl -ne 'use locale; print uc'
éLèVE



Chez moi ça marche. Tes locales sont probablement mal configurées.



Il y a sans aucun doute un problème mais je ne vois vraiment pas où...

% locale
LANG LC_CTYPE=fr_FR.utf8
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL % locale -a | grep fr_FR.utf8
fr_FR.utf8
% printf 'élèven' | od -atx1
0000000 C ) l C ( v e nl
c3 a9 6c c3 a8 76 65 0a
0000010
% printf 'élèven' | gawk '{ print toupper($0) }'
ÉLÈVE
% printf 'élèven' | tr '[:lower:]' '[:upper:]'
éLèVE
% printf 'élèven' | sed 's/.*/U&/'
ÉLÈVE

Ceci dit, use locale est bâti sur une API bancale, donc il vaudrait
mieux ne pas l'utiliser.



Et quelle est l'alternative ?

--
Benoit Izac
Nicolas George
Le #19454651
Paul Gaborit wrote in message
L'API est bancale mais la solution PERL_UNICODE me semble l'être
encore plus.



Je suis d'accord : forcer Unicode sur des scripts qui ne sont pas prévus
pour, en particulier qui pourraient essayer de manipuler des données
binaires, c'est casse-figure.

En revanche, -C ou -CSDLA sur les scripts qui en ont besoin me semble une
solution tout à fait acceptable.

Je pense que la réglage correct des locales est absolument
nécessaire...



Évidemment.
Nicolas George
Le #19454641
Benoit Izac wrote in message
Il y a sans aucun doute un problème mais je ne vois vraiment pas où...



En fait, apparemment, use locale ne marche pas pour une locale UTF-8. C'est
vraiment nul comme API.
Nicolas George
Le #19454631
Benoit Izac wrote in message
Sachant que j'ai encore pas mal de fichiers dans mon répertoire qui sont
en ISO-8859-1(5), quelles peuvent-être les conséquences d'exporter
PERL_UNICODE=SDA :
- pour mon shell interactif ?



La même chose que pour la suite, pour tous les programmes qui seraient
lancés depuis ce shell.

Avoir des réglages d'environnement faits spécifiquement pour les shells
interactifs me semble vraiment absurde.

- dans l'environnement global de ma machine (pour tous les
programmes) ?



Tu risques de casser tous les programmes perl qui s'attendent spécifiquement
à recevoir des données binaires, ou bien qui gèrent du texte de manière fine
(par exemple en détectant l'encodage).

Question subsidiaire : pourquoi ceci (-C L) ne fonctionne pas ?



Parce que -C L tout seul, ça veut dire, en fonction de la locale (L) de
faire... rien du tout. Il faut l'accoler à un autre flag pour qu'il ait de
l'effet.
Benoit Izac
Le #19454781
Bonjour,

le 31/05/2009 à 10:56, Nicolas George a écrit dans le message

Sachant que j'ai encore pas mal de fichiers dans mon répertoire qui
sont en ISO-8859-1(5), quelles peuvent-être les conséquences
d'exporter PERL_UNICODE=SDA :
- pour mon shell interactif ?



La même chose que pour la suite, pour tous les programmes qui seraient
lancés depuis ce shell.

Avoir des réglages d'environnement faits spécifiquement pour les
shells interactifs me semble vraiment absurde.



On s'éloigne de Perl mais sur une machine avec plusieurs utilisateurs
qui ont chacun une langue différente, c'est la seule manière de
faire à ma connaissance.

- dans l'environnement global de ma machine (pour tous les
programmes) ?



Tu risques de casser tous les programmes perl qui s'attendent
spécifiquement à recevoir des données binaires, ou bien qui gèrent du
texte de manière fine (par exemple en détectant l'encodage).



Comment détecter l'encodage ?

Question subsidiaire : pourquoi ceci (-C L) ne fonctionne pas ?



Parce que -C L tout seul, ça veut dire, en fonction de la locale (L)
de faire... rien du tout. Il faut l'accoler à un autre flag pour qu'il
ait de l'effet.



Effectivement, ça marche parfaitement avec PERL_UNICODE='ADSL'.

Donc pour conclure, il n'y a pas de méthode actuellement pour écrire un
script Perl portable (le programmeur n'a pas de moyen de savoir
l'environnement dans lequel va s'exécuter son script).

--
Benoit Izac
Nicolas George
Le #19454941
Benoit Izac wrote in message
On s'éloigne de Perl mais sur une machine avec plusieurs utilisateurs
qui ont chacun une langue différente, c'est la seule manière de
faire à ma connaissance.



C'est faux, heureusement !

C'est même doublement faux : régler l'environnement dans le shell interactif
n'aura aucun effet sur les applications lancées par les sessions graphiques,
ou par ssh avec une commande.

Et heureusement, il existe des solutions pour régler l'environnement dans
ces différents cas. La manière de procéder dépend des types de sessions
qu'on souhaite couvrir, mais pour chaque type de session, il est possible de
régler l'environnement.

Comment détecter l'encodage ?



Personnellement, j'essaie successivement les possibilités plausibles dans un
ordre judicieusement choisi (les plus strictes en premier), en demandant une
erreur quand l'encodage est invalide.

Donc pour conclure, il n'y a pas de méthode actuellement pour écrire un
script Perl portable (le programmeur n'a pas de moyen de savoir
l'environnement dans lequel va s'exécuter son script).



Qu'est-ce qui te fait dire ça ? Il faut programmer soigneusement, en
rajoutait des :bytes partout où c'est nécessaire, mais c'est tout à fait
possible.

Ceci dit, personnellement, je considère que régler globalement un paramètre
qui change le comportement par défaut d'un langage est une très mauvaise
idée, et je considère quand je programme qu'un administrateur qui s'est
amusé à le faire cherche les bugs et que c'est tant pis pour lui s'il en
trouve.

Donc en l'occurrence, je programme comme si $PERL_UNICODE était indéfinie,
donc que toutes les entrées-sorties sont par défaut en :bytes (windows et
les vieux macos inexistent), et je les passe en ce que je veux si besoin
est.
Publicité
Poster une réponse
Anonyme