Comments 53
О!) Что именно всё же значит — Wide characters in print и как это эффективно бороть, не зная заранее с какой кодировкой работаешь?=)
Значит, что в файловый дескриптор напечатаны данные с UTF-флагом. Вариантов куча, есть правильные, есть удобные.
0) Идеальное решение — сделать так, чтобы данные всегда были в одном единственном формате.
1) no warnings 'layer' — самый эффективный способ избавиться от варнингов :)
2) при помощи open или binmode укажите адекватную кодировку для файлового дескриптора. open подойдет для открываемых Вами файлов, binmode — для уже открытых дескрипторов типа STDOUT. Тут может возникнуть конфуз, если на печать пойдут обычные байты, без флага — данные покоцает.
3) ручками следите за тем, что печатаете, и при необходимости опускайте флажок
0) Идеальное решение — сделать так, чтобы данные всегда были в одном единственном формате.
1) no warnings 'layer' — самый эффективный способ избавиться от варнингов :)
2) при помощи open или binmode укажите адекватную кодировку для файлового дескриптора. open подойдет для открываемых Вами файлов, binmode — для уже открытых дескрипторов типа STDOUT. Тут может возникнуть конфуз, если на печать пойдут обычные байты, без флага — данные покоцает.
3) ручками следите за тем, что печатаете, и при необходимости опускайте флажок
А если речь идёт не о файле, а о получаемых «извне» — в данном случае — из интернета «скалярах»?)
Я нашёл модуль Фитцпатрика — is_utf8 — и мы экспериментировали с «шириной» символа — но эффективно побороть не удалось всё же(
Я нашёл модуль Фитцпатрика — is_utf8 — и мы экспериментировали с «шириной» символа — но эффективно побороть не удалось всё же(
UFO just landed and posted this here
Угу. У нас все входные данные автоматически перекодируются из кодировки сайта в utf-форму, потом стараемся работать только с уникодом.
хм. То есть я правильно понимаю, что получаемая wide characters — это свидетельство флага юникода?
Да. Любое упоминание про wide characters это свидетельство уникода, причем с utf-флагом
Ну тогда получается, что бывает флаг юникода у получаемых откуда-то данных? Я же могу доверять своим глазам :)
Если конкретно — то через LWP получаемых=)
Если конкретно — то через LWP получаемых=)
UFO just landed and posted this here
Попробуйте сразу после получения данных (совсем сразу!!) проверить их функцией is_utf8. Уверен, флага не будет. Ну и ниже проверочки по коду раскидайте, особенно если Вы к переменной с результатами LWP что-либо конкатенируете (даже цифру или пустую строку).
Кстати о цифрах. Когда я впервые столкнулся с уникодом, мне нужно было вклеить результаты разбора XML в письмо. Я честно опустил флаг у всего что можно было, но шаблон все равно портился из-за двойной перекодировки. Единственное что я не сделал — пропустил без изменений одну циферку. Проблема была там.
Кстати о цифрах. Когда я впервые столкнулся с уникодом, мне нужно было вклеить результаты разбора XML в письмо. Я честно опустил флаг у всего что можно было, но шаблон все равно портился из-за двойной перекодировки. Единственное что я не сделал — пропустил без изменений одну циферку. Проблема была там.
Расскажу интересную историю. Правда, детали я уже успел подзабыть, так что где-то могу ошибиться. Если кто-то поправит, а еще лучше, подкрепит примерами из исходников Perl, буду признателен.
Где-то полгода назад мне пришлось разбираться, как на низком уровне работает поддержка UTF8 в Perl (включая изучение исходников и т.д.). И выяснилась одна очень интересная деталь: по сути, вся встроенная «ядровая» поддержка ограничивается этим самым флагом is_utf8 с минимальной его интерпретацией. Все остальное сделано на Perl-коде. Например, для полноценной работы с Unicode Perl так или иначе подключает encoding.pm, а также 500-килобайтные файлы из lib/Unicode (а возможно, из lib/unicore — я сейчас уже не вспомню). Причем делается это довольно интересно: в Perl-коде можно повесить недокументированный «callback» на ряд операций с unicode-данными, и этот callback будет вызываться из Си-кода ядра Perl. При этом модули типа encoding.pm подсовывают в роли данного callback-а… код на Perl, работающий с огромными файлами в lib/Unicode. Т.е. из ядра Perl вызывается Perl-код, а ядро ничего про Unicode не знает (оно знает про флаг is_utf8, но интерпретирует его только как подсказку для вызова хуков; с тем же успехом он мог называться is_blablabla). Так что с этой точки зрения в Perl по-настоящему встроенной поддержки Unicode как не было, так и нет.
Все это я обнаружил, пытаясь минимизировать объем Perl-кода, который должен поставляться вместе с perl.exe для работы с Unicode. Я просто начал постепенно удалять файлы и смотреть, что происходит. По зависимостям потянулись описанные выше явления.
Почему они не использовали стандартный и проверенный iconv для поддержки Unicode, а сделали обработку через хуки, для меня так и осталось загадкой.
В итоге, как это ни печатльно, по совокупности причин пришлось отказаться от «встроенной» поддержки Unicode совсем (т.к. без файлов в lib/Unicode флаг is_utf8 бесполезен), вместо этого полагаясь на старый механизм и выполняя перекодировки вручную, где это необходимо (вопрос объема и скорости загрузки был критичен). Также я пришел к выводу, что поддержка Unicode в Perl — весьма костыльная, или уж — во всяком случае — по своей чистоте сильно проигрывает таковой в Javascript и Python. Она примерно такая же костыльная, как в PHP5, а может, даже и хуже (потому что в PHP есть какой-никакой встроенный mbstring).
Где-то полгода назад мне пришлось разбираться, как на низком уровне работает поддержка UTF8 в Perl (включая изучение исходников и т.д.). И выяснилась одна очень интересная деталь: по сути, вся встроенная «ядровая» поддержка ограничивается этим самым флагом is_utf8 с минимальной его интерпретацией. Все остальное сделано на Perl-коде. Например, для полноценной работы с Unicode Perl так или иначе подключает encoding.pm, а также 500-килобайтные файлы из lib/Unicode (а возможно, из lib/unicore — я сейчас уже не вспомню). Причем делается это довольно интересно: в Perl-коде можно повесить недокументированный «callback» на ряд операций с unicode-данными, и этот callback будет вызываться из Си-кода ядра Perl. При этом модули типа encoding.pm подсовывают в роли данного callback-а… код на Perl, работающий с огромными файлами в lib/Unicode. Т.е. из ядра Perl вызывается Perl-код, а ядро ничего про Unicode не знает (оно знает про флаг is_utf8, но интерпретирует его только как подсказку для вызова хуков; с тем же успехом он мог называться is_blablabla). Так что с этой точки зрения в Perl по-настоящему встроенной поддержки Unicode как не было, так и нет.
Все это я обнаружил, пытаясь минимизировать объем Perl-кода, который должен поставляться вместе с perl.exe для работы с Unicode. Я просто начал постепенно удалять файлы и смотреть, что происходит. По зависимостям потянулись описанные выше явления.
Почему они не использовали стандартный и проверенный iconv для поддержки Unicode, а сделали обработку через хуки, для меня так и осталось загадкой.
В итоге, как это ни печатльно, по совокупности причин пришлось отказаться от «встроенной» поддержки Unicode совсем (т.к. без файлов в lib/Unicode флаг is_utf8 бесполезен), вместо этого полагаясь на старый механизм и выполняя перекодировки вручную, где это необходимо (вопрос объема и скорости загрузки был критичен). Также я пришел к выводу, что поддержка Unicode в Perl — весьма костыльная, или уж — во всяком случае — по своей чистоте сильно проигрывает таковой в Javascript и Python. Она примерно такая же костыльная, как в PHP5, а может, даже и хуже (потому что в PHP есть какой-никакой встроенный mbstring).
Да, для тех, кто захочет копать. Ключевые слова: SWASH, SWASHGET, encoding.pm, utf8.pm, open.pm. (Кстати, мне никогда не нравилось называть «use utf8» и другие похожие штуки вроде «use strict» прагмой, потому что все «прагмы» на самом деле — обыкновенные модули на Perl. Как правило, они подменяют разные «плохо документированные» переменные типа $^W, которые влияют на результаты компиляции.)
Да, и еще: в 5.10 такая же история, как в 5.8. Ничего не изменилось.
В чём костыльность-то? Вы хотели, чтобы все функции были реализованы в одном бинарнике интерпретатора?
Спасибо за комментарий, настолько глубоко я не копал. Но то, что реализация оставляет желать лучшего — это факт. Даже с банальным вебом проблема — у нас на сервере вывод буферизируется в перловую переменную, неловкое движение с флагом — и кусок страницы испорчен. Да и вообще неудобно. Но наверное это лучше чем совсем ничего. Ждем perl6, там вроде обещали полноценный strict utf зашитый по самое нехочу.
Как на Javascript подсчитать md5/sha1 сумму от не-ASCII файла?
Хорошая статья.Спасибо. Только вот на PERL я практически не программирую. Написал бы ктонибудь подобную по php ато даже mb_string не во всех случаях помогает.
UFO just landed and posted this here
Почему погода показывается только для Москвы?
GeoIP отменили? Сделали хотя бы выбор города — ведь и того нет.
GeoIP отменили? Сделали хотя бы выбор города — ведь и того нет.
UFO just landed and posted this here
Было бы неплохо, если бы хоть кто-нибудь объяснил, зачем нам PHP :)
Этот блог посвящен именно перлу, Ваш вопрос здесь выглядит несколько странно.
Этот блог посвящен именно перлу, Ваш вопрос здесь выглядит несколько странно.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
Хм, кажется я Вас не совсем понял вначале, сорри.
Выбор языка во многом субъективен. Одно дело, когда язык выбирается осмысленно под конкретную задачу — скажем, Perl принято хвалить за его возможности по работе со строками (которые последнее время можно найти в любом другом языке), C++ хвалят за скорость работы ну и т.д. Perl и PHP во многом похожи и под веб-задачу имхо можно пользоваться любым из них, в зависимости от предпочтений. Когда я знакомился с PHP, некоторые принятые там принципы, вроде подключения библиотек, встали мне поперек горла, и я этот язык оставил. Возможно, сейчас многое изменилось, но разбираться в PHP у меня желание пропало. Когда будет нечего делать, лучше питон поковыряю :)
Выбор языка во многом субъективен. Одно дело, когда язык выбирается осмысленно под конкретную задачу — скажем, Perl принято хвалить за его возможности по работе со строками (которые последнее время можно найти в любом другом языке), C++ хвалят за скорость работы ну и т.д. Perl и PHP во многом похожи и под веб-задачу имхо можно пользоваться любым из них, в зависимости от предпочтений. Когда я знакомился с PHP, некоторые принятые там принципы, вроде подключения библиотек, встали мне поперек горла, и я этот язык оставил. Возможно, сейчас многое изменилось, но разбираться в PHP у меня желание пропало. Когда будет нечего делать, лучше питон поковыряю :)
UFO just landed and posted this here
Ну не совсем соглашусь. Для МАЛЕНЬКИХ веб-задач, действительно, выбор CGI Perl или PHP — вопрос предпочтения, и они похожи. А вот когда дело доходит до проектов с большим объемом кода и высокими нагрузками, то выбор встает не совсем между Perl и PHP, а скорее между mod_perl и PHP (или между FastCGI Perl и PHP). Названия похожи, а вот методики разработки и архитектура очень сильно различны.
Отличная статья, единственно, я бы убрал термин «wide characters» из параграфа под «The Perl Way», поскольку в мире статических-компиляторов под ним чаще всего понимаются элементы UTF-16/UCS2, а в perl-мире это только путает. Есть только байты и символы (числа от 0 до 2^32-1 на 32-битных платформах).
Отлично написано, keep it up!
Очень-очень напоминает мой (Mons Anderson) доклад, особенно в части примеров кода.
Либо мы очень сходно мыслим, либо кто-то случайно забыл указать используемые источники ;)
Либо мы очень сходно мыслим, либо кто-то случайно забыл указать используемые источники ;)
ты б дал ссылочку на презенташку свою с докладом или на текстовый его вариант, если таки написал уже +)
Ну презенташка — не вопрос.
taka.xfo.cc/utf8.xul
А вот статью так и не выложил
т.е. есть она только в том спецвыпуске «Сетевых решений», который был сделан к By Perl
www.nestor.minsk.by/sr/2008/09/sr80902.html
taka.xfo.cc/utf8.xul
А вот статью так и не выложил
т.е. есть она только в том спецвыпуске «Сетевых решений», который был сделан к By Perl
www.nestor.minsk.by/sr/2008/09/sr80902.html
Статья писалась полностью из головы. Единственный действительно придуманный пример кода приведен в разделе «грабли», остальные естественным образом взяты из перлдоков, список которых приведен в конце статьи ;-)
А где можно посмотреть на доклад? Если он на эту же тему, я просто прицеплю его в конце статьи, читатели будут только рады.
А где можно посмотреть на доклад? Если он на эту же тему, я просто прицеплю его в конце статьи, читатели будут только рады.
А что с юникодом в 6-й версии планируется?
Топорное решение, без модулей:
%unicode = (
"%u0430" => «а», "%u0431" => «б», "%u0432" => «в»,
"%u0433" => «г», "%u0434" => «д», "%u0435" => «е»,
…
);
$query_value =~ s/(%u[0-9A-F]{4})/$unicode{$1}/eg;
(добавил к паре слов...)
%unicode = (
"%u0430" => «а», "%u0431" => «б», "%u0432" => «в»,
"%u0433" => «г», "%u0434" => «д», "%u0435" => «е»,
…
);
$query_value =~ s/(%u[0-9A-F]{4})/$unicode{$1}/eg;
(добавил к паре слов...)
Sign up to leave a comment.
Пара слов про UTF-8