还包括Perl的Net ::卡桑德拉模块支持UTF-8?
题
我碰到一个很奇怪的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
的代码。我在做什么错了?
解决方案
添加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字节序列的字符串,它应该被转换成Unicode的Perl的内部表示。作为jrockway指出,还应该呼吁任何字符串Encode::encode_utf8
它们被发送到卡桑德拉之前,虽然在大多数情况下的Perl已经知道他们是UTF-8,例如,如果你打开与:utf8
编码层的文件。
如果您使用UTF-8的时候,你可能要改写的Net ::卡桑德拉::简单的包装来自动执行此操作。
最后,你不需要use utf8;
除非你的Perl的源代码的(可变的名称的,评论等)包含UTF-8字符。 Perl可以处理UTF-8的字符串的你是否指定use utf8;
与否。
不隶属于 StackOverflow