Вопрос

Я столкнулся с действительно странной проблемой UTF-8 с Net::Cassandra::Easy (который построен на Net::Cassandra):Строки UTF-8, записанные в Cassandra, искажаются при извлечении.

Следующий код показывает проблему:

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

При выполнении приведенного выше кода $set_value eq $get_value оценивает, чтобы false.Что я делаю не так?

Это было полезно?

Решение

Добавить use Encode; к началу вашего скрипта и передайте переменные через Encode::decode_utf8.Например:

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

Результаты:

OK: ☃ == ☃

Когда вы устанавливаете $set_value для "\x{2603}" Perl определяет широкий символ и устанавливает для вас кодировку строки в UTF-8.Чтобы подтвердить это, выведите возвращаемое значение Encode::is_utf8($set_value).

К сожалению, как только эта строка переходит в Cassandra и возвращается обратно, информация о кодировке теряется.Похоже, что Кассандра не зависит от кодирования.Зовущий Encode::decode_utf8 сообщает Perl, что у вас есть строка, содержащая последовательность байтов UTF-8, и что ее следует преобразовать во внутреннее представление Perl для Unicode.Как указывает jrockway, вам также следует позвонить Encode::encode_utf8 в любых строках перед их отправкой в Cassandra, хотя в большинстве случаев Perl уже знает, что они имеют формат UTF-8, например, если вы открыли файл с :utf8 уровень кодирования.

Если вы часто используете UTF-8, возможно, вам захочется написать оболочку поверх Net::Cassandra::Easy, чтобы сделать это автоматически.

Наконец, вам не нужно use utf8; если только ваш Perl исходный код (переменная имена, комментарии и т.д.) содержит символы UTF-8.Perl может обрабатывать UTF-8 струны указываете ли вы use utf8; или нет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top