O módulo Net::Cassandra do Perl suporta UTF-8?
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?
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.