В очередной раз задумался о том, какие строки оптимальней использовать в основном коде: characters или octets.
Обычно мне очень редко приходиться работать непосредственно с unicode. Когда нужно, я преобразовываю octets в characters, а затем обратно.
Но HTML::Parser требует на вход unicode, и JSON::XS корректно работает только с unicode. Поэтому хоть непосредственно я сам не использую characters, приходиться перекодировать при помощи модуля Encode.
Кроме этих модулей, обычно все работают с octets.
А вот при работе над магазинчиком вышивки бисером и нитками Embroidery Kits выяснилось, что остальные используемый модули могут работать как с octets, так и с characters (кроме Digest::SHA).
HTML::Parser и JSON::XS перетянули одеяло на себя. Задумался.
P.S.
Utf8 флаг в сложных структурах данных расставляю, сбрасываю при помощи нижеприведенного кода.
use Encode;
use Scalar::Util qw(looks_like_number);
sub data_walk($$);
sub data_walk($$) {
my ($d,$s) = @_;
if (ref $d eq "ARRAY") {
$d = [ map { data_walk($_, $s) } @$d ];
} elsif (ref $d eq "HASH") {
$d = { map { $s->($_) => data_walk($$d{$_}, $s) } keys %$d };
} elsif (not ref $d) {
$d = $s->($d)
}
return $d;
}
sub data_encode_utf8 { data_walk(shift,
sub {
my $data = shift;
if ($data and not looks_like_number($data)) {
$data = Encode::encode_utf8($data) if Encode::is_utf8($data);
}
return $data;
}
)
}
sub data_decode_utf8 { data_walk(shift,
sub {
my $data = shift;
if ($data and not looks_like_number($data)) {
$data = Encode::decode_utf8($data, Encode::FB_QUIET) unless Encode::is_utf8($data);
$data ||= "ERROR: FOR SOME REASON, TEXT CONVERSION TO UTF8 FAILED";
}
return $data;
}
)
}