2. 2
Перейти с CP1251 на Unicode.
В Web приложении на Perl
Сотни тысяч строк Perl кода
Сайт, бэкофис, много скриптов
Регистрация IDN доменов на разных языках.
3. Чтобы работать с текстом на разных языках
одновременно.
to unicode or not to unicode
3
4. Чтобы работать с текстом на разных языках
одновременно.
to unicode or not to unicode
Даже для одного языка - однобайтные кодировки - не
вариант
4
5. use Modern::Perl;
print "YESn" if "x85" =~ /^s+$/;
__END__
YES
to unicode or not to unicode
lc(), uc(), w W s S и т.д. могут не работать
5
x85 в cp1251 это
6. Текстовые строки
Внутренний
формат
Как интерпретируются Как
интерпретируется
0xD0 0xAF
С флагом
UTF-8
(Unicode)
Строка считается
последовательностью
unicode символов,
закодированных в UTF-8
Один символ "Я"
(unicode U+042F)
Без флага
UTF-8
Каждый байт - один
символ
Два символа с кодами
(U+00D0 U+00AF )
6
7. Сделать так чтобы один и тот код работал со строками в
разных форматах (unicode или cp1251)
Работаем одновременно в разных
кодировках
В зависимости от конфига, приложение сможет работать
то в одной кодировке то в другой
7
"Старый" код будет совместим только с режимом работы
в формате cp1251
8. sub func {
my ($s) = @_; # $s либо cp1251 либо unicode
to_unicode($s); # теперь $s - точно unicode
$s =~ s/(W+)/_/g; # текстовая операция
from_unicode($s); # $s в том формате что и было
return $s;
}
Работаем одновременно в разных
кодировках
8
Как выглядит такой код
9. sub func {
my ($s) = @_; # $s либо cp1251 либо unicode
$s = Encode::decode("CP1251", $s); # to_unicode($s)
$s =~ s/(W+)/_/g; # текстовая операция
$s = Encode::encode("CP1251", $s); # from_unicode($s)
return $s;
}
Работаем одновременно в разных
кодировках
9
Как этот код работает в режиме CP1251
10. sub func {
my ($s) = @_; # $s либо cp1251 либо unicode
# to_unicode($s) - ничего не делает!
$s =~ s/(W+)/_/g; # текстовая операция
# from_unicode($s) - ничего не делает!
return $s;
}
Работаем одновременно в разных
кодировках
10
Как этот код работает в режиме Unicode
11. Работаем одновременно в разных
кодировках
11
Режим to_unicode from_unicode
CP1251 CP1251 ->
UNICODE
UNICODE ->
CP1251
Unicode NOP NOP
12. Работаем одновременно в разных
кодировках
12
Режим to_unicode from_unicode to_cp1251 from_cp1251
CP1251 CP1251 ->
UNICODE
UNICODE ->
CP1251
NOP NOP
Unicode NOP NOP UNICODE ->
CP1251
CP1251 ->
UNICODE
13. $value =~ /Привет/i # исходник в CP1251
Что ещё нужно сделать с кодом
13
Строковые константы
use utf8;
$value =~ /Привет/i; # исходник в UTF-8
Было
Стало
14. Что ещё нужно сделать с кодом
14
Расширенное толкование метасимволов регэкспов
Теперь это тоже d
15. Что ещё нужно сделать с кодом
15
Ввод-вывод
to_unicode($str);
open my $fh, ">:encoding(UTF-8)", $filename;
print $fh $str;
22. Только байты. Никакого текста.
22
Redis, Redis::Fast
Perl не может отличить байты от текста
Используем сериализацию. Например Storable.
только сериализация которая восстанавливает все скаляры в оригинальном виде
27. 27
Сложные структуры данных
sub myfunc {
my ($str) = @_;
to_unicode_recursive $str; # в unicode
$is_greetings = $str->{field} =~ /Привет/i;
die if rand() > 0.5; # проблема
from_unicode_recursive $str; # обратно
return $is_greetings;
}
28. 28
Сложные структуры данных
sub myfunc {
my ($str) = @_;
my $str_u = to_unicode_clone $str; # в unicode
my $is_greetings = $str_u->{field} =~ /Привет/i;
die if rand() > 0.5; # нет проблем!
# обратно перекодировать не нужно
return $is_greetings;
}
29. 29
Сложные структуры данных
my $dataref = +{
x => [1,2,3,"тест"],
y => { a => 42 },
z => bless { field => "привет"}, 'MyObject'
};
to_unicode_recursive($dataref); # ошибка
31. В общем Redis сервере кэшируются фрагменты html в
разных кодировках
31
Запуск на production
Веб приложение пишет в базу символы, которых нет в
cp1251, значит cp1251 процессы их “не увидят”
32. Написание возможно в 2 строки
Плашку регулировать по длине текста
Вывод или посыл зрителю
Спасибо!
Буду рад ответить
на ваши вопросы!
E-mail:
efimov@reg.ru
32