[Perl] UTF8 hash key downgraded when assigned

Kai Carver kai.carver at gmail.com
Sam 1 Déc 08:14:15 CET 2018


hello Gérard

curieux...

j'ai vu ceci:

"It appears to be a bug the optimisation of constant hash keys. The
constant key string in $h{'Góry'} is being downgraded from utf8, whereas if
you write my $g = 'Góry'; $h{$g} = 1; it works ok."
https://www.perlmonks.org/index.pl?node_id=1197369

et effectivement le bug ne se produit pas si au lieu d'utiliser 'clé' tu
utilises une variable $cle = 'clé'

#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Devel::Peek;
use Data::Dumper;
$Data::Dumper::Useqq = 1;

my $cle = 'clé';
my %hash = (
    $cle => 0,
);
my $key = (keys %hash)[0];
Dump($key);
print Dumper($key);

$hash{$cle} = 1;
$key = (keys %hash)[0];

Dump($key);
print Dumper($key);

utf8::upgrade($key);
Dump($key);
print Dumper($key);

On Sat, Dec 1, 2018 at 1:03 AM Gérald SÉDRATI-DINET <
gerald at sedrati-dinet.net> wrote:

> Salut les Mongueurs!
>
> Ça faisait longtemps que je n'avais pas posté ici, mais maintenant que
> j'ai la joie de retravailler en Perl, j'ai aussi celle de partager à
> nouveau de vos lumières :)
>
> Je suis tombé sur un étrange comportement, sur toutes les versions de
> Perl que j'ai pu testées (entre la 5.16 et la 5.26).
>
> Il y a une question sur stack overflow
> (
> https://stackoverflow.com/questions/8418496/hash-keys-encoding-why-do-i-get-here-with-develpeekdump-two-different-resul
> )
> qui date de quelques années mais sans réponse s'il s'agit ou non d'un
> bug d'optimisation ou d'un comportement normal.
>
> Le problème et que si vous initialisez un hash avec une clé ayant des
> caractères non-ascii (par ex. du iso-8859-1), la clé est correctement
> encodée en UTF8 (avec le flag UTF8 positionné). Mais si vous assignez
> ensuite une valeur à l'élément du hash correspondant à cette clé,
> celle-ci est déclassée (comme avec un utf8::downgrade, probablement
> encodée en iso-8859-1). Je vous laisse imaginer les conséquences si vous
> avez à manipuler cette clé pour une raison ou pour une autre, en vous
> attendant à ce qu'elle soit encodée en  UTF8…
>
> Voilà un script montrant le problème:
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
> use utf8;
> use Devel::Peek;
> use Data::Dumper;
> $Data::Dumper::Useqq = 1;
>
> my %hash = (
>     'clé' => 0,
> );
> my $key = (keys %hash)[0];
> Dump($key);
> print Dumper($key);
>
> $hash{'clé'} = 1;
> $key = (keys %hash)[0];
>
> Dump($key);
> print Dumper($key);
>
> utf8::upgrade($key);
> Dump($key);
> print Dumper($key);
> [download]
>
> avec le résultat suivant:
>
> SV = PV(0x555ed17dfe60) at 0x555ed1809710
>   REFCNT = 1
>   FLAGS = (POK,pPOK,UTF8)
>   PV = 0x555ed1993ed0 "cl\303\251"\0 [UTF8 "cl\x{e9}"]
>   CUR = 4
>   LEN = 5
> $VAR1 = "cl\x{e9}";
> SV = PV(0x555ed17dfe60) at 0x555ed1809710
>   REFCNT = 1
>   FLAGS = (POK,IsCOW,pPOK)
>   PV = 0x555ed1909b10 "cl\351"
>   CUR = 3
>   LEN = 0
> $VAR1 = "cl\351";
> SV = PV(0x555ed17dfe60) at 0x555ed1809710
>   REFCNT = 1
>   FLAGS = (POK,pPOK,UTF8)
>   PV = 0x555ed1825350 "cl\303\251"\0 [UTF8 "cl\x{e9}"]
>   CUR = 4
>   LEN = 10
> $VAR1 = "cl\x{e9}";
> [download]
>
> Comme dans ce code, on peut résoudre le problème en surclassant en UTF8
> (utf8::upgrade) la clé. Mais j'aurais jamais imaginé devoir faire ça
> avant de tomber sur le problème. J'ai rien lu dans perldoc qui explique
> ce comportement.
>
> Vous avez une idée d'explication, si c'est ou non voulu ?
>
> Merci!
> --
> Gérald Sédrati-Dinet
> https://pascontent.sedrati-dinet.net     https://www.april.org
> https://www.unitary-patent.eu            https://laquadrature.net
>
> _______________________________________________
> Perl mailing list
> Perl at mongueurs.net
> http://listes.mongueurs.net/mailman/listinfo/perl
> Attention, les archives sont publiques
-------------- section suivante --------------
Une pièce jointe HTML a été nettoyée...
URL: <http://listes.mongueurs.net/archives/perl/attachments/20181201/5b7797e2/attachment.html>


Plus d'informations sur la liste de diffusion Perl