1

私は本当に奇妙なUTF-8の問題に遭遇しましたNet::Cassandra::Easy(これはに基づいていますNet::Cassandra):Cassandraに書き込まれたUTF-8文字列は取得時に文字化けします。

次のコードは問題を示しています。

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ます。私は何を間違っていますか?

4

1 に答える 1

4

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 に入って再び戻ると、エンコーディング情報は失われます。Cassandra はエンコーディングに依存していないようです。呼び出しEncode::decode_utf8は、UTF-8 バイト シーケンスを含む文字列があり、Unicode の Perl の内部表現に変換する必要があることを Perl に伝えます。jrockway が指摘しているようEncode::encode_utf8に、Cassandra に送信される前に文字列を呼び出す必要がありますが、ほとんどの場合、たとえば:utf8エンコーディング レイヤーでファイルを開いた場合など、Perl は文字列が UTF-8 であることを既に認識しています。

UTF-8 を頻繁に使用する場合は、Net::Cassandra::Easy にラッパーを記述して、これを自動的に行うことができます。

use utf8;最後に、 Perlソース コード(変数、コメントなど) に UTF-8 文字が含まれていない限り、必要ありません。Perl は、指定するかどうかにかかわらず、 UTF-8文字列use utf8;を処理できます。

于 2010-03-27T10:47:26.120 に答える