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?

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top