Каких проблем следует ожидать при переносе устаревшего кода Perl в UTF-8?

До сих пор проект, над которым я работаю, использовал ASCII только в исходном коде. Из-за нескольких предстоящих изменений в области I18N, а также из-за того, что нам нужны некоторые строки Unicode в наших тестах, мы думаем о том, чтобы укусить пулю и переместить исходный код в UTF-8, используя прагму utf8 (use utf8;)

Поскольку код сейчас находится в ASCII, я не ожидаю, что у меня возникнут проблемы с самим кодом. Однако я не совсем осведомлен о каких-либо побочных эффектах, которые мы можем получить, хотя я думаю, что вполне вероятно, что я их получу, учитывая нашу среду (perl5.8.8, Apache2, mod_perl, MSSQL Server с драйвером FreeTDS).

Если вы уже делали такие миграции в прошлом: каких проблем я могу ожидать? Как я могу ими управлять?


person Nikolai Prokoschenko    schedule 25.11.2009    source источник
comment
Когда я изменяю свой исходный код с системной кодировки GB2312 по умолчанию на UTF8 и применяю прагму use utf8, код больше не сможет открывать файлы, имена которых закодированы в GB2312.   -  person Mike    schedule 25.11.2009


Ответы (2)


Несколько лет назад я переместил нашу внутреннюю платформу mod_perl (~ 35k LOC) на UTF-8. Вот что нам нужно было учесть / изменить:

  • несмотря на совет perl doc «только там, где это необходимо», используйте «use utf8»; в каждом исходном файле - это дает последовательность.
  • преобразуйте вашу базу данных в UTF-8 и убедитесь, что ваша конфигурация БД устанавливает кодировку соединения в UTF-8 (в MySQL, при этом обратите внимание на проблемы с длиной поля с VARCHAR)
  • используйте последнюю версию DBI - более старые версии неправильно устанавливают флаг utf8 для возвращаемых скаляров
  • используйте модуль Encode, избегайте использования встроенных в Perl функций utf8, если вы точно не знаете, с какими данными вы имеете дело
  • при чтении файлов UTF-8 укажите слой - open($fh,"<:utf8",$filename)
  • в ОС в стиле RedHat (даже выпусках 2008 года) включенным библиотекам не понравится чтение XML-файлов, хранящихся в скалярах utf8 - обновите perl или просто используйте слой :raw
  • в старых версиях Perl (даже версиях 5.8.x) некоторые старые строковые функции могут быть непредсказуемыми - например. $b=substr(lc($utf8string),0,2048) случайным образом не работает, но $a=lc($utf8string);$b=substr($a,0,2048) работает!
  • не забудьте преобразовать ваш ввод - например. в веб-приложении входящие данные формы могут нуждаться в декодировании
  • убедитесь, что все сотрудники разработчиков знают, каковы условия кодирования / декодирования - строка utf8 в perl находится в / de / -coded форме, необработанная строка байтов, содержащая данные utf8, / en / -coded
  • правильно обрабатывать свои URL-адреса - / en / -кодировать строку utf8 в байты, а затем выполнить кодировку% xx для создания ASCII-формы URL-адреса и / де / -кодировать ее при чтении из mod_perl (например, $uri=utf_decode($r->uri()))
  • еще один для веб-приложений, помните, что кодировка в заголовке HTTP переопределяет кодировку, указанную с помощью <meta>
  • Я уверен, что это само собой разумеется - если вы выполняете какие-либо байтовые операции (например, пакетные данные, побитовые операции, даже заголовок MIME Content-Length), убедитесь, что вы выполняете вычисления с байтами, а не с символами
  • убедитесь, что ваши разработчики знают, как обеспечить, чтобы их текстовые редакторы были настроены на UTF-8, даже если для данного файла нет спецификации
  • не забудьте убедиться, что ваша система контроля версий (для удобства Google - subversion / svn) правильно обрабатывает файлы
  • где возможно, придерживайтесь ASCII для имен файлов и имен переменных - это позволяет избежать проблем с переносимостью при перемещении кода или использовании различных инструментов разработчика.

Еще одно - это золотое правило - не взламывайте, пока это не сработает, убедитесь, что вы полностью понимаете, что происходит в данной ситуации кодирования / декодирования!

Я уверен, что вы уже разобрались с большинством из них, но, надеюсь, все это поможет кому-то избежать многочасовой отладки, через которую мы прошли.

person John O'Rourke    schedule 27.11.2009

Прагма utf8 просто сообщает Perl, что ваш исходный код закодирован в UTF-8. Если вы использовали в исходном коде только ASCII, у вас не возникнет проблем с пониманием исходного кода Perl. Возможно, вы захотите создать ветку в системе управления версиями на всякий случай. :)

Если вам нужно иметь дело с данными UTF-8 из файлов или записывать UTF-8 в файлы, вам необходимо установить кодировки на файловых дескрипторах и закодировать данные в соответствии с ожиданиями внешних битов. См., Например, Может ли Perl-скрипт с кодировкой utf8 открыть имя файла с кодировкой GB2312?.

Ознакомьтесь с документацией Perl, в которой рассказывается о Unicode:

См. Также совет Джурда по Perl Unicode.

person brian d foy    schedule 25.11.2009