SlideShare a Scribd company logo
1 of 32
Download to read offline
11
Unicode в Perl и как перевести на него
систему
Виктор Ефимов
2
Перейти с CP1251 на Unicode.
В Web приложении на Perl
Сотни тысяч строк Perl кода
Сайт, бэкофис, много скриптов
Регистрация IDN доменов на разных языках.
Чтобы работать с текстом на разных языках
одновременно.
to unicode or not to unicode
3
Чтобы работать с текстом на разных языках
одновременно.
to unicode or not to unicode
Даже для одного языка - однобайтные кодировки - не
вариант
4
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 это
Текстовые строки
Внутренний
формат
Как интерпретируются Как
интерпретируется
0xD0 0xAF
С флагом
UTF-8
(Unicode)
Строка считается
последовательностью
unicode символов,
закодированных в UTF-8
Один символ "Я"
(unicode U+042F)
Без флага
UTF-8
Каждый байт - один
символ
Два символа с кодами
(U+00D0 U+00AF )
6
Сделать так чтобы один и тот код работал со строками в
разных форматах (unicode или cp1251)
Работаем одновременно в разных
кодировках
В зависимости от конфига, приложение сможет работать
то в одной кодировке то в другой
7
"Старый" код будет совместим только с режимом работы
в формате cp1251
sub func {
my ($s) = @_; # $s либо cp1251 либо unicode
to_unicode($s); # теперь $s - точно unicode
$s =~ s/(W+)/_/g; # текстовая операция
from_unicode($s); # $s в том формате что и было
return $s;
}
Работаем одновременно в разных
кодировках
8
Как выглядит такой код
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
sub func {
my ($s) = @_; # $s либо cp1251 либо unicode
# to_unicode($s) - ничего не делает!
$s =~ s/(W+)/_/g; # текстовая операция
# from_unicode($s) - ничего не делает!
return $s;
}
Работаем одновременно в разных
кодировках
10
Как этот код работает в режиме Unicode
Работаем одновременно в разных
кодировках
11
Режим to_unicode from_unicode
CP1251 CP1251 ->
UNICODE
UNICODE ->
CP1251
Unicode NOP NOP
Работаем одновременно в разных
кодировках
12
Режим to_unicode from_unicode to_cp1251 from_cp1251
CP1251 CP1251 ->
UNICODE
UNICODE ->
CP1251
NOP NOP
Unicode NOP NOP UNICODE ->
CP1251
CP1251 ->
UNICODE
$value =~ /Привет/i # исходник в CP1251
Что ещё нужно сделать с кодом
13
Строковые константы
use utf8;
$value =~ /Привет/i; # исходник в UTF-8
Было
Стало
Что ещё нужно сделать с кодом
14
Расширенное толкование метасимволов регэкспов
Теперь это тоже d
Что ещё нужно сделать с кодом
15
Ввод-вывод
to_unicode($str);
open my $fh, ">:encoding(UTF-8)", $filename;
print $fh $str;
Тестирование
16
package MyClass;
use utf8;
sub myfunc {
my ($x, $data) = @_;
do_something($data);
if ($x == 42) {
do_even_more($data);
$s =~ s/Ё/Е/g;
}
}
Тестирование
17
package MyClass;
use utf8;
sub myfunc {
my ($x, $data) = @_;
do_something($data);
if ($x == 42) { # Always TRUE
do_even_more($data);
$s =~ s/Ё/Е/g;
}
}
Test::Spec
18
Тестирование
Test::Spec::Mocks
$myobj->expects('do_something')->with("Привет")->
returns("Тест");
MyApp->config( encoding => 'UTF-8' )
19
Catalyst
Content-Type: text/html; charset=utf-8
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8">
Перекодировать шаблоны
20
Template Toolkit
my $provider = Template->new({
ENCODING => 'utf8',
});
SET NAMES 'cp1251' SET NAMES 'utf8'
21
DBI, DBD::mysql
Только байты. Никакого текста.
22
Redis, Redis::Fast
Perl не может отличить байты от текста
Используем сериализацию. Например Storable.
только сериализация которая восстанавливает все скаляры в оригинальном виде
Почта
23
Другие большие подсистемы
Логи
Что-то ещё.. Индивидуальный подход к каждой.
sha256("привет") - не определено!
24
Пароли
sha256(utf8("привет")) <> sha256(cp1251("привет"))
Бизнес-логика - потом
25
Бизнес-логика
Проверяем что входные данные - валидируются
26
Сложные структуры данных
my $dataref = +{
x => [1,2,3,"тест"],
y => { a => 42 },
};
to_unicode_recursive($dataref);
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
Сложные структуры данных
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
Сложные структуры данных
my $dataref = +{
x => [1,2,3,"тест"],
y => { a => 42 },
z => bless { field => "привет"}, 'MyObject'
};
to_unicode_recursive($dataref); # ошибка
30
Запуск на production
Module1.pm (unicode ok)
Module2.pm (unicode ok)
Module3.pm (unicode ok)
Module4.pm (legacy)
script1.pl
script2.pl
ps#2618
unicode
ps#2621
unicode
ps#2622
CP1251
ps#2626
CP1251
ps#2624
CP1251
В общем Redis сервере кэшируются фрагменты html в
разных кодировках
31
Запуск на production
Веб приложение пишет в базу символы, которых нет в
cp1251, значит cp1251 процессы их “не увидят”
Написание возможно в 2 строки
Плашку регулировать по длине текста
Вывод или посыл зрителю
Спасибо!
Буду рад ответить
на ваши вопросы!
E-mail:
efimov@reg.ru
32

More Related Content

What's hot

Сергей Пузанков — XPath
Сергей Пузанков — XPathСергей Пузанков — XPath
Сергей Пузанков — XPathYandex
 
Python
PythonPython
Pythonpelid
 
Js Http Request дмитрий котеров
Js Http Request   дмитрий котеровJs Http Request   дмитрий котеров
Js Http Request дмитрий котеровMedia Gorod
 
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?tfmailru
 
Интернационализация и локализация в Symfony / Symfony I18n And L10n
Интернационализация и локализация в Symfony / Symfony I18n And L10nИнтернационализация и локализация в Symfony / Symfony I18n And L10n
Интернационализация и локализация в Symfony / Symfony I18n And L10nIgor Brovchenko
 
Многоязычные сайты на Symfony. Проблемы и их решения
Многоязычные сайты на Symfony. Проблемы и их решенияМногоязычные сайты на Symfony. Проблемы и их решения
Многоязычные сайты на Symfony. Проблемы и их решенияIgor Brovchenko
 
Present saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPresent saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPavel Vlasov
 

What's hot (13)

Funny JS #1
Funny JS #1Funny JS #1
Funny JS #1
 
Сергей Пузанков — XPath
Сергей Пузанков — XPathСергей Пузанков — XPath
Сергей Пузанков — XPath
 
Collider
ColliderCollider
Collider
 
Python
PythonPython
Python
 
Js Http Request дмитрий котеров
Js Http Request   дмитрий котеровJs Http Request   дмитрий котеров
Js Http Request дмитрий котеров
 
Perl: Symbol table
Perl: Symbol tablePerl: Symbol table
Perl: Symbol table
 
лекц15
лекц15лекц15
лекц15
 
Python i18n
Python i18nPython i18n
Python i18n
 
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
Tarantool: как обрабатывать 
1,5 млрд запросов в сутки?
 
Интернационализация и локализация в Symfony / Symfony I18n And L10n
Интернационализация и локализация в Symfony / Symfony I18n And L10nИнтернационализация и локализация в Symfony / Symfony I18n And L10n
Интернационализация и локализация в Symfony / Symfony I18n And L10n
 
Многоязычные сайты на Symfony. Проблемы и их решения
Многоязычные сайты на Symfony. Проблемы и их решенияМногоязычные сайты на Symfony. Проблемы и их решения
Многоязычные сайты на Symfony. Проблемы и их решения
 
Perl – жив?!
Perl – жив?!Perl – жив?!
Perl – жив?!
 
Present saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPresent saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasov
 

Viewers also liked

Developing a Demand-Driven Acquisitions Plan: A Library-Vendor Collaboration
Developing a Demand-Driven Acquisitions Plan: A Library-Vendor CollaborationDeveloping a Demand-Driven Acquisitions Plan: A Library-Vendor Collaboration
Developing a Demand-Driven Acquisitions Plan: A Library-Vendor CollaborationMichael Levine-Clark
 
Projeto prnto para o blog
Projeto prnto para o blogProjeto prnto para o blog
Projeto prnto para o blogDiego Mendes
 
Alicepresentation
AlicepresentationAlicepresentation
Alicepresentationecsmedia
 
20091127 Ec Gaal Estali 2
20091127 Ec Gaal Estali 220091127 Ec Gaal Estali 2
20091127 Ec Gaal Estali 2gaalnorb
 
Furqan_CV1
Furqan_CV1Furqan_CV1
Furqan_CV1gis1234
 
Competition in-acrostics-for-winter-olympics-2014 (1)
Competition in-acrostics-for-winter-olympics-2014 (1)Competition in-acrostics-for-winter-olympics-2014 (1)
Competition in-acrostics-for-winter-olympics-2014 (1)Xenia Nincevic
 
British Council Talk
British Council TalkBritish Council Talk
British Council Talkseaninchina
 
A successful project sharing
A successful project sharingA successful project sharing
A successful project sharingPhuoc Nguyen
 
Presentation a beam_of_hope_rev1.3
Presentation a beam_of_hope_rev1.3Presentation a beam_of_hope_rev1.3
Presentation a beam_of_hope_rev1.3Makoto Oya
 
BALWOIS_2012
BALWOIS_2012BALWOIS_2012
BALWOIS_2012D Kannan
 
ATIVIDADES DO LIVRO :MISTÉRIO NO GALINHEIRO
ATIVIDADES DO LIVRO :MISTÉRIO NO GALINHEIROATIVIDADES DO LIVRO :MISTÉRIO NO GALINHEIRO
ATIVIDADES DO LIVRO :MISTÉRIO NO GALINHEIRODiego Mendes
 

Viewers also liked (20)

Developing a Demand-Driven Acquisitions Plan: A Library-Vendor Collaboration
Developing a Demand-Driven Acquisitions Plan: A Library-Vendor CollaborationDeveloping a Demand-Driven Acquisitions Plan: A Library-Vendor Collaboration
Developing a Demand-Driven Acquisitions Plan: A Library-Vendor Collaboration
 
Projeto prnto para o blog
Projeto prnto para o blogProjeto prnto para o blog
Projeto prnto para o blog
 
Mi Hermano
Mi HermanoMi Hermano
Mi Hermano
 
Back on track
Back on trackBack on track
Back on track
 
Essay mode 5
Essay mode 5Essay mode 5
Essay mode 5
 
Alicepresentation
AlicepresentationAlicepresentation
Alicepresentation
 
20091127 Ec Gaal Estali 2
20091127 Ec Gaal Estali 220091127 Ec Gaal Estali 2
20091127 Ec Gaal Estali 2
 
CURSO DE TEOLOGIA
CURSO DE TEOLOGIACURSO DE TEOLOGIA
CURSO DE TEOLOGIA
 
Furqan_CV1
Furqan_CV1Furqan_CV1
Furqan_CV1
 
アクセシビリティへの取り組みの歴史
アクセシビリティへの取り組みの歴史アクセシビリティへの取り組みの歴史
アクセシビリティへの取り組みの歴史
 
Diapositivas
DiapositivasDiapositivas
Diapositivas
 
Competition in-acrostics-for-winter-olympics-2014 (1)
Competition in-acrostics-for-winter-olympics-2014 (1)Competition in-acrostics-for-winter-olympics-2014 (1)
Competition in-acrostics-for-winter-olympics-2014 (1)
 
British Council Talk
British Council TalkBritish Council Talk
British Council Talk
 
Personality traits
Personality traitsPersonality traits
Personality traits
 
Drupal Rules!
Drupal Rules!Drupal Rules!
Drupal Rules!
 
A successful project sharing
A successful project sharingA successful project sharing
A successful project sharing
 
Presentation a beam_of_hope_rev1.3
Presentation a beam_of_hope_rev1.3Presentation a beam_of_hope_rev1.3
Presentation a beam_of_hope_rev1.3
 
Autonoom
AutonoomAutonoom
Autonoom
 
BALWOIS_2012
BALWOIS_2012BALWOIS_2012
BALWOIS_2012
 
ATIVIDADES DO LIVRO :MISTÉRIO NO GALINHEIRO
ATIVIDADES DO LIVRO :MISTÉRIO NO GALINHEIROATIVIDADES DO LIVRO :MISTÉRIO NO GALINHEIRO
ATIVIDADES DO LIVRO :MISTÉRIO NO GALINHEIRO
 

Similar to виктор ефимов «Unicode в perl и как перевести на него систему» (yapc russia 2014, спб)

Что нового в Perl 5.14
Что нового в Perl 5.14Что нового в Perl 5.14
Что нового в Perl 5.14Andrew Shitov
 
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Yandex
 
Внешние языки DSL на funcparserlib
Внешние языки DSL на funcparserlibВнешние языки DSL на funcparserlib
Внешние языки DSL на funcparserlibAndrey Vlasovskikh
 
Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Pavel Tsukanov
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentAnton Kirillov
 
Доклад на Highload-2012
Доклад на Highload-2012Доклад на Highload-2012
Доклад на Highload-2012Alex Tutubalin
 
Интеграция Яндекс Сервер
Интеграция Яндекс СерверИнтеграция Яндекс Сервер
Интеграция Яндекс СерверPVasili
 
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...phpdevby
 
Эффективное использование x86-совместимых CPU (Алексей Тутубалин)
Эффективное использование x86-совместимых CPU (Алексей Тутубалин)Эффективное использование x86-совместимых CPU (Алексей Тутубалин)
Эффективное использование x86-совместимых CPU (Алексей Тутубалин)Ontico
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013ScalaNsk
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Sergey Platonov
 
CodeFest 2012. Нелюбин Д. — Neo4j — графовая база данных
CodeFest 2012. Нелюбин Д. — Neo4j — графовая база данныхCodeFest 2012. Нелюбин Д. — Neo4j — графовая база данных
CodeFest 2012. Нелюбин Д. — Neo4j — графовая база данныхCodeFest
 
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...Magneta AI
 
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)Ontico
 
Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Alexander Kirillov
 
Сергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
Сергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглитьСергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
Сергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглитьTanya Denisyuk
 

Similar to виктор ефимов «Unicode в perl и как перевести на него систему» (yapc russia 2014, спб) (20)

Что нового в Perl 5.14
Что нового в Perl 5.14Что нового в Perl 5.14
Что нового в Perl 5.14
 
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
 
UWDC 2013, Yii2
UWDC 2013, Yii2UWDC 2013, Yii2
UWDC 2013, Yii2
 
Приручаем linux-консоль
Приручаем linux-консольПриручаем linux-консоль
Приручаем linux-консоль
 
Transpile it.pdf
Transpile it.pdfTranspile it.pdf
Transpile it.pdf
 
Внешние языки DSL на funcparserlib
Внешние языки DSL на funcparserlibВнешние языки DSL на funcparserlib
Внешние языки DSL на funcparserlib
 
Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?Ruby - или зачем мне еще один язык программирования?
Ruby - или зачем мне еще один язык программирования?
 
Scala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application DevelopmentScala, SBT & Play! for Rapid Application Development
Scala, SBT & Play! for Rapid Application Development
 
Доклад на Highload-2012
Доклад на Highload-2012Доклад на Highload-2012
Доклад на Highload-2012
 
Интеграция Яндекс Сервер
Интеграция Яндекс СерверИнтеграция Яндекс Сервер
Интеграция Яндекс Сервер
 
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...MongoDB. Области применения, преимущества и узкие места, тонкости использован...
MongoDB. Области применения, преимущества и узкие места, тонкости использован...
 
Эффективное использование x86-совместимых CPU (Алексей Тутубалин)
Эффективное использование x86-совместимых CPU (Алексей Тутубалин)Эффективное использование x86-совместимых CPU (Алексей Тутубалин)
Эффективное использование x86-совместимых CPU (Алексей Тутубалин)
 
Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013Павел Павлов - Scala для профессионалов - Joker 2013
Павел Павлов - Scala для профессионалов - Joker 2013
 
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++ Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
Юрий Ефимочев, Компилируемые в реальном времени DSL для С++
 
MySQL 101
MySQL 101MySQL 101
MySQL 101
 
CodeFest 2012. Нелюбин Д. — Neo4j — графовая база данных
CodeFest 2012. Нелюбин Д. — Neo4j — графовая база данныхCodeFest 2012. Нелюбин Д. — Neo4j — графовая база данных
CodeFest 2012. Нелюбин Д. — Neo4j — графовая база данных
 
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
Scala, Play Framework и SBT для быстрого прототипирования и разработки веб-пр...
 
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
MySQL 5.7 - NoSQL - JSON, Protocol X, Document Store / Петр Зайцев (Percona)
 
Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)
 
Сергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
Сергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглитьСергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
Сергей Аверин, То, что вы хотели знать о HandlerSocket, но не смогли нагуглить
 

виктор ефимов «Unicode в perl и как перевести на него систему» (yapc russia 2014, спб)

  • 1. 11 Unicode в Perl и как перевести на него систему Виктор Ефимов
  • 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;
  • 16. Тестирование 16 package MyClass; use utf8; sub myfunc { my ($x, $data) = @_; do_something($data); if ($x == 42) { do_even_more($data); $s =~ s/Ё/Е/g; } }
  • 17. Тестирование 17 package MyClass; use utf8; sub myfunc { my ($x, $data) = @_; do_something($data); if ($x == 42) { # Always TRUE do_even_more($data); $s =~ s/Ё/Е/g; } }
  • 19. MyApp->config( encoding => 'UTF-8' ) 19 Catalyst Content-Type: text/html; charset=utf-8 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  • 20. Перекодировать шаблоны 20 Template Toolkit my $provider = Template->new({ ENCODING => 'utf8', });
  • 21. SET NAMES 'cp1251' SET NAMES 'utf8' 21 DBI, DBD::mysql
  • 22. Только байты. Никакого текста. 22 Redis, Redis::Fast Perl не может отличить байты от текста Используем сериализацию. Например Storable. только сериализация которая восстанавливает все скаляры в оригинальном виде
  • 23. Почта 23 Другие большие подсистемы Логи Что-то ещё.. Индивидуальный подход к каждой.
  • 24. sha256("привет") - не определено! 24 Пароли sha256(utf8("привет")) <> sha256(cp1251("привет"))
  • 25. Бизнес-логика - потом 25 Бизнес-логика Проверяем что входные данные - валидируются
  • 26. 26 Сложные структуры данных my $dataref = +{ x => [1,2,3,"тест"], y => { a => 42 }, }; to_unicode_recursive($dataref);
  • 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); # ошибка
  • 30. 30 Запуск на production Module1.pm (unicode ok) Module2.pm (unicode ok) Module3.pm (unicode ok) Module4.pm (legacy) script1.pl script2.pl ps#2618 unicode ps#2621 unicode ps#2622 CP1251 ps#2626 CP1251 ps#2624 CP1251
  • 31. В общем Redis сервере кэшируются фрагменты html в разных кодировках 31 Запуск на production Веб приложение пишет в базу символы, которых нет в cp1251, значит cp1251 процессы их “не увидят”
  • 32. Написание возможно в 2 строки Плашку регулировать по длине текста Вывод или посыл зрителю Спасибо! Буду рад ответить на ваши вопросы! E-mail: efimov@reg.ru 32