IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Incompréhension du pragma use utf8


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 376
    Par défaut Incompréhension du pragma use utf8
    Bonjour,

    J'ai un souci de compréhension sur le comportement de perl a propos du pragma utf8, voici le cas:
    Juste pour montré que le caractère est bien en utf8:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ echo -n "é" | hexdump -C
    00000000  c3 a9                                             |..|
    00000002
    ici, perl le traite bien comme un caractère utf8:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ perl -e 'print "é"' | hexdump -C
    00000000  c3 a9                                             |..|
    00000002
    Maintenant, lorsque l'on rajoute le pragma use utf8, perl me le transforme en autre chose que de l'utf8:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ perl -e 'use utf8;print "é"' | hexdump -C
    00000000  e9                                                |.|
    00000001
    J'ai ce cas quand j'ai des chaines directement déclarée dans un scalair, par contre, si je récupère la chaine depuis un fichier, dans les 2 cas (avec ou sans utf8), le caractère reste inchangé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $ echo -n "é" | perl -ne 'print $_' | hexdump -C
    00000000  c3 a9                                             |..|
    00000002
    $ echo -n "é" | perl -ne 'use utf8;print $_' | hexdump -C
    00000000  c3 a9                                             |..|
    00000002
    Ce que je ne comprend pas, c'est le cas de la déclaration dans un scalair, j'aurais plus pensé intuitivement à un comportement inverse ou identique.

    Si quelqu'un a une réponse, je suis preneur.

  2. #2
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 452
    Par défaut
    Bonjour,

    C'est étonnant en effet et je n'ai pas d'explication très rationnelle...

    J'ai ce cas quand j'ai des chaines directement déclarée dans un scalair, par contre, si je récupère la chaine depuis un fichier, dans les 2 cas (avec ou sans utf8), le caractère reste inchangé:
    En ce qui me concerne j'ai rencontré des pb en traitant des caractères arabes.
    Je veille a être cohérent partout, c'est à dire :
    - Fichier en lecture et/ou écriture en UTF-8
    - J'utilise toujours le pragma :
    dans mes fichiers sources.pl, justement pour avoir des scalaires qui sortent correctement,
    - Mais de plus je dois sauvegarder mes sources.pl en UTF-8 NO BOM (avec Ultraedit) UTF-8 devrait suffire...

    Ceci étant, dans tes exemples, chez moi en Perl v5.22.2 j'ai une anomalie de signalée pour ton cas précis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    perl -ne 'use utf8;print "é"' | hexdump -C
    Pour tenter une explication :
    - Lorsque la source est un fichier .pl il y a bien interprétation et conversion
    - Lorsque la source est injectée depuis le fichier STDIN par un echo elle sort correctement
    - Lorsque la source n'est pas injectée mais communiquée à Perl directement par print il n'y aurait pas d'interprétation
    En ligne de commande le pragma qui doit interpréter les caractères provenant d'une source ne fonctionnerait pas.
    Mais c'est juste histoire de retomber sur mes pattes

    Donc pour ton cas, veille à sauvegarder tes sources en UTF-8

  3. #3
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 376
    Par défaut
    Sauf que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ cat essaix.pl
    #!/usr/bin/env perl
     
    use strict;
    use warnings;
    use utf8;
     
    my $toto='é';
    print $toto . "\n";
    Le type du fichier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ file -i essaix.pl
    essaix.pl: text/plain; charset=utf-8
    un hexdump pour bien voir que le "é" est bien en utf8:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $ hexdump -C essaix.pl
    00000000  23 21 2f 75 73 72 2f 62  69 6e 2f 65 6e 76 20 70  |#!/usr/bin/env p|
    00000010  65 72 6c 0a 0a 75 73 65  20 73 74 72 69 63 74 3b  |erl..use strict;|
    00000020  0a 75 73 65 20 77 61 72  6e 69 6e 67 73 3b 0a 75  |.use warnings;.u|
    00000030  73 65 20 75 74 66 38 3b  0a 0a 6d 79 20 24 74 6f  |se utf8;..my $to|
    00000040  74 6f 3d 27 c3 a9 27 3b  0a 70 72 69 6e 74 20 24  |to='é';.print $|
    00000050  74 6f 74 6f 20 2e 20 22  5c 6e 22 3b 0a           |toto . "\n";.|
    0000005d
    Et si on exécute le script, le caractère est modifié tout comme la ligne de commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ ./essaix.pl | hexdump -C
    00000000  e9 0a                                             |..|
    00000002
    Et si on retire le pragma utf8, le caractère reste inchangé...

  4. #4
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 452
    Par défaut
    Oui, j'ai oublié le pb Invite_de_commande/Terminal/Console

    L'invite de commande... n'étant pas compatibles UTF-8...

    Dans tous mes scripts je colle le Super, le Fameux... ... ActiverAccents(); de dijbril

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #!/usr/bin/env perl
     
    use strict;
    use warnings;
    use utf8;
     
     
    # Pour avoir les accents dans l'invite de commande (Console/Terminal)
    ActiverAccents();
     
     
    my $toto='é';
    print $toto . "\n";
     
    #==============================================================
    # Pour avoir les accents sur la console DOS
    # http://perl.developpez.com/faq/perl/?page=Terminal#AccentsDOS
    #==============================================================
    sub ActiverAccents {
    	my $encodage;
    	# Windows
      	if ( lc($^O ) eq 'mswin32') {                           # Si je suis sur Windows
    		eval {
    			my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ );          # On récupère le nombre que renvoie chcp dans une invite de commande
    			                                                      # exemple : Page de codes active*: 437
    			$encodage = "cp$codepage";                            # On accole ce nombre au libellé "cp" de façon avoir cp437
    			foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {      # pour les fichiers spéciaux sortie_Ecran, Sortie_Erreur, Clavier_Entrée
    				binmode $h, ":encoding($encodage)";                 # djibril modifie l'encodage ;)
    			}
    		};	
    	}
    	else {                                                    # SINON je suis dans Unix / Linux
    		$encodage = `locale charmap`;                           # On récupère l'encodage par défaut, mais avec la commande qui va bien
    		eval {
    			foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {      # djibril modifie l'encodage des fichiers spéciaux ;)
    				binmode $h, ":encoding($encodage)";
    			}
    		};	
    	}
      return $encodage;                                         # Retourne le bon encodage suivant l'OS
    }
     
    #Sinon petit rappel pour info :
    #ü 	\x81 	à 	\x85 	è 	\x8A
    #é 	\x82 	ç 	\x87 	ï 	\x8B
    #â 	\x83 	ê 	\x88 	î 	\x8C
    #ä 	\x84 	ë 	\x89
    [Edit 13:13] Ajout Terminal Cygwin
    et dans un terminal ont voit bien dans le cat que les caractères UTF-8 sont mal interprétés
    par contre avec la fonction ActiverAccents();
    le print est OK

  5. #5
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 376
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 376
    Par défaut
    Ok, mais par exemple, le code unicode et utf8 du "é" est:
    Unicode
    code point
    character UTF-8
    (in literal)
    name
    U+00E9 é \xc3\xa9 LATIN SMALL LETTER E WITH ACUTE
    Et au vu de ce que me retourne le cas avec le pragma utf8, celui-ci me transforme le caractère utf8 en unicode.
    D'ailleurs, je viens de trouver ce que fait perl lorsque l'on utilise le pragma utf8:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ perl -e 'use utf8; $toto="é"; print $toto . "\n"'| hexdump -C
    00000000  e9 0a                                             |..|
    00000002
    $ perl -e 'use utf8; $toto="é"; utf8::decode($toto);print $toto . "\n"' | hexdump -C
    00000000  e9 0a                                             |..|
    00000002
    $ perl -e 'use utf8; $toto="é"; utf8::encode($toto);print $toto . "\n"' | hexdump -C
    00000000  c3 a9 0a                                          |é.|
    00000003
    Celui-ci fait un decode de la chaine, ce qui fait que l'on obtient le \xe9, alors qu'intuitivement, on s'attendrait à ce qu'il fasse, en fait, un encode...

    Après, est-ce normal d'avoir ce comportement, là cela me dépasse

  6. #6
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 452
    Par défaut
    Oh !
    Entre le normal et l'intuitif il y a souvent un univers de différence... et pas seulement en informatique

    Trêve de plaisanterie c'est bien parce que je n'obtenais pas ce que j’imaginais intuitivement que je me suis imposé l'UTF-8 sur toute la ligne : Fichiers E/S & code.
    Ce n'est pas ce qu'il y a de plus économique en taille de fichier, mais au moins je sais (à peu près) où j'en suis

    Quand j'ai commencé en informatique les caractères étaient codés sur 6 bits on appelait çà l'EBCDIC, là on avait pas même droit aux accents...
    et comme on avait pas beaucoup de mémoire on coupaient les caractères en deux, trois ou quatre (c'est le cas de le dire...) pour stocker le numérique...
    Bull avait même inventé l'octet de 9 bits , avec un mots machine de 4 caractères = 36 bits, on y stockaient soit 9 caractères alphabétiques, soit 12 caractères numériques... l'opulence QUOI !
    On passait déjà notre temps à faire des conversions...

    Il faut comprendre qu'on a à disposition un demi-siècle de codification des caractères.
    Les personnes qui ont dû faire les choix qui nous étonnent, avaient elles, les contraintes de la compatibilité ascendante...
    C'est devenu un millefeuille, mais je ne me sens pas de taille à leur jeter une pierre...

    Pourquoi on ne peut toujours pas écrire en arabe, en tibétain, en thaïlandais, en japonnais... dans une invite de commande, une console, un terminal ?
    Les intéressés eux-mêmes ne s'en plaignent pas
    Tu n'en demandes pas tant, parce que tu n'en as pas l’utilité, pourtant ça serait "normal" !

    J'ai dans mes favoris l'ensemble des codes, dès que j'ai un doute ou un pb, je vérifie plutôt que de faire confiance à mon intuition, parce qu'à chaque fois que je le fais je me plante

    Dans les derniers exemples que tu as collé, on a non seulement rien qui correspond à nos intuitions mais aussi des anomalies de signalées...

    Perso je suis devenu docile, je ne me pose plus la question de la normalité, surtout en informatique, je suis conscient que j'ai été formaté par les ordinateurs
    Alors je me fie à Spinoza :
    "Par réalité et par perfection j'entends la même chose."
    Désolé, je m'en tire comme je peux

    Bonne continuation !

  7. #7
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par disedorgue Voir le message
    Et au vu de ce que me retourne le cas avec le pragma utf8, celui-ci me transforme le caractère utf8 en unicode.
    D'ailleurs, je viens de trouver ce que fait perl lorsque l'on utilise le pragma utf8:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ perl -e 'use utf8; $toto="é"; print $toto . "\n"'| hexdump -C
    00000000  e9 0a                                             |..|
    00000002
    $ perl -e 'use utf8; $toto="é"; utf8::decode($toto);print $toto . "\n"' | hexdump -C
    00000000  e9 0a                                             |..|
    00000002
    $ perl -e 'use utf8; $toto="é"; utf8::encode($toto);print $toto . "\n"' | hexdump -C
    00000000  c3 a9 0a                                          |é.|
    00000003
    Celui-ci fait un decode de la chaine, ce qui fait que l'on obtient le \xe9, alors qu'intuitivement, on s'attendrait à ce qu'il fasse, en fait, un encode...
    Non, le pragma utf8 se contente d'interpréter le code de ton programme (donc, y compris les chaînes de caractères contenues dans tes variables) comme de l'UTF8. Mais il n'effectue aucune sorte de conversion, et n'a pas en lui-même d'influence sur les entrées et sorties.

    Je te conseille de lire ceci: http://perl.developpez.com/tutoriels...e-guide-perl5/, peut-être que ça clarifiera la question.

    Sinon, je n'en dis pas plus sur ton problème, car je ne suis pas sûr de bien le comprendre.

Discussions similaires

  1. use package utf8
    Par boss89 dans le forum Mise en forme
    Réponses: 3
    Dernier message: 26/07/2012, 11h19
  2. [débutant] incompréhension "using"..
    Par Arnaokee dans le forum C#
    Réponses: 8
    Dernier message: 22/07/2010, 10h23
  3. incompréhension utf8, caractère é.
    Par Sylvain__A_ dans le forum Langage
    Réponses: 6
    Dernier message: 08/12/2008, 14h13
  4. [WSAD5] probleme incompréhensible
    Par capitaine_banane dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 07/04/2004, 11h56
  5. Connaitre l'unitée à ajouter dans USES
    Par DelphiCool dans le forum Langage
    Réponses: 7
    Dernier message: 01/08/2002, 13h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo