Pergunta

Eu me deparei com um problema UTF-8 muito estranho com Net::Cassandra::Easy (que é construído sobre Net::Cassandra):As strings UTF-8 gravadas em Cassandra são distorcidas na recuperação.

O código a seguir mostra o problema:

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";
}

Ao executar o código acima $set_value eq $get_value avalia para false.O que estou fazendo de errado?

Foi útil?

Solução

Adicionar use Encode; para o início do seu script e passe variáveis ​​através Encode::decode_utf8.Por exemplo:

my $get_value = $result->{$key}->{"Standard1"}->{$column};
$get_value = Encode::decode_utf8($get_value);

Saídas:

OK: ☃ == ☃

Quando você define $set_value para "\x{2603}", o Perl detecta o caractere largo e define a codificação da string como UTF-8 para você.Para confirmar isso, imprima o valor de retorno de Encode::is_utf8($set_value).

Infelizmente, uma vez que essa string entra no Cassandra e sai novamente, as informações de codificação são perdidas.Parece que Cassandra é independente de codificação.Chamando Encode::decode_utf8 informa ao Perl que você possui uma string contendo uma sequência de bytes UTF-8 e que ela deve ser convertida na representação interna do Perl para Unicode.Como aponta jrockway, você também deve ligar Encode::encode_utf8 em qualquer string antes de serem enviadas para Cassandra, embora na maioria dos casos o Perl já saiba que são UTF-8, por exemplo, se você abriu um arquivo com o :utf8 camada de codificação.

Se você usa UTF-8 com frequência, você pode querer escrever um wrapper em Net::Cassandra::Easy para fazer isso automaticamente.

Finalmente, você não precisa use utf8; a menos que seu Perl Código fonte (variável nomes, comentários etc.) contém caracteres UTF-8.Perl pode lidar com UTF-8 cordas se você especifica use utf8; ou não.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top