Est-ce que le Net de Perl :: Support module Cassandra UTF-8?
Question
J'ai rencontré un problème UTF-8 vraiment étrange avec Net::Cassandra::Easy
(qui est construit sur Net::Cassandra
):. Chaînes UTF-8 écrites à Cassandra sont tronqués sur la récupération
Le code suivant montre le problème:
use strict;
use utf8;
use warnings;
use Net::Cassandra::Easy;
binmode(STDOUT, ":utf8");
my $key = "some_key";
my $column = "some_column";
my $set_value = "\x{2603}"; # U+2603 is ☃ (SNOWMAN)
my $cassandra = Net::Cassandra::Easy->new(keyspace => "Keyspace1", server => "localhost");
$cassandra->connect();
$cassandra->mutate([$key], family => "Standard1", insertions => { $column => $set_value });
my $result = $cassandra->get([$key], family => "Standard1", standard => 1);
my $get_value = $result->{$key}->{"Standard1"}->{$column};
if ($set_value eq $get_value) {
# this is the path I want.
print "OK: $set_value == $get_value\n";
} else {
# this is the path I get.
print "ERR: $set_value != $get_value\n";
}
Lors de l'exécution du code ci-dessus $set_value eq $get_value
évalue à false
. Qu'est-ce que je fais mal?
La solution
Ajouter use Encode;
au début de votre script, et passer des variables par Encode::decode_utf8
. Par exemple:
my $get_value = $result->{$key}->{"Standard1"}->{$column};
$get_value = Encode::decode_utf8($get_value);
Sorties:
OK: ☃ == ☃
Lorsque vous définissez $set_value
à « \ x {2603} », Perl détecte le caractère large et définit l'encodage de chaîne en UTF-8 pour vous. Pour confirmer, imprimer la valeur de retour de Encode::is_utf8($set_value)
.
Malheureusement, une fois que cette chaîne va dans Cassandra et revenir à nouveau, les informations de codage est perdu. Il semble que Cassandra est un codage agnostique. L'appel Encode::decode_utf8
indique à Perl que vous avez une chaîne contenant une séquence d'octets UTF-8, et qu'il devrait être converti en représentation interne de Perl pour Unicode. Comme jrockway souligne, vous devez également appeler Encode::encode_utf8
sur toutes les chaînes avant d'être envoyés à Cassandra, bien que dans la plupart des cas Perl sait déjà qu'ils sont UTF-8, par exemple si vous avez ouvert un fichier avec la couche de codage :utf8
.
Si vous utilisez UTF-8 souvent, vous voudrez peut-être écrire un wrapper sur Net :: Cassandra :: Facile à faire automatiquement.
Enfin, vous n'avez pas besoin use utf8;
à moins que vos (noms variable , commentaires, etc.) Perl code source contient caractères UTF-8. Perl peut gérer UTF-8 chaînes si vous spécifiez use utf8;
ou non.