Comments 53
О!) Что именно всё же значит — Wide characters in print и как это эффективно бороть, не зная заранее с какой кодировкой работаешь?=)
0
Значит, что в файловый дескриптор напечатаны данные с 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) ручками следите за тем, что печатаете, и при необходимости опускайте флажок
+1
А если речь идёт не о файле, а о получаемых «извне» — в данном случае — из интернета «скалярах»?)
Я нашёл модуль Фитцпатрика — is_utf8 — и мы экспериментировали с «шириной» символа — но эффективно побороть не удалось всё же(
Я нашёл модуль Фитцпатрика — is_utf8 — и мы экспериментировали с «шириной» символа — но эффективно побороть не удалось всё же(
0
UFO just landed and posted this here
Угу. У нас все входные данные автоматически перекодируются из кодировки сайта в utf-форму, потом стараемся работать только с уникодом.
0
хм. То есть я правильно понимаю, что получаемая wide characters — это свидетельство флага юникода?
0
Да. Любое упоминание про wide characters это свидетельство уникода, причем с utf-флагом
0
Ну тогда получается, что бывает флаг юникода у получаемых откуда-то данных? Я же могу доверять своим глазам :)
Если конкретно — то через LWP получаемых=)
Если конкретно — то через LWP получаемых=)
0
UFO just landed and posted this here
Попробуйте сразу после получения данных (совсем сразу!!) проверить их функцией is_utf8. Уверен, флага не будет. Ну и ниже проверочки по коду раскидайте, особенно если Вы к переменной с результатами LWP что-либо конкатенируете (даже цифру или пустую строку).
Кстати о цифрах. Когда я впервые столкнулся с уникодом, мне нужно было вклеить результаты разбора XML в письмо. Я честно опустил флаг у всего что можно было, но шаблон все равно портился из-за двойной перекодировки. Единственное что я не сделал — пропустил без изменений одну циферку. Проблема была там.
Кстати о цифрах. Когда я впервые столкнулся с уникодом, мне нужно было вклеить результаты разбора XML в письмо. Я честно опустил флаг у всего что можно было, но шаблон все равно портился из-за двойной перекодировки. Единственное что я не сделал — пропустил без изменений одну циферку. Проблема была там.
0
Расскажу интересную историю. Правда, детали я уже успел подзабыть, так что где-то могу ошибиться. Если кто-то поправит, а еще лучше, подкрепит примерами из исходников 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).
+4
Да, для тех, кто захочет копать. Ключевые слова: SWASH, SWASHGET, encoding.pm, utf8.pm, open.pm. (Кстати, мне никогда не нравилось называть «use utf8» и другие похожие штуки вроде «use strict» прагмой, потому что все «прагмы» на самом деле — обыкновенные модули на Perl. Как правило, они подменяют разные «плохо документированные» переменные типа $^W, которые влияют на результаты компиляции.)
+1
Да, и еще: в 5.10 такая же история, как в 5.8. Ничего не изменилось.
0
В чём костыльность-то? Вы хотели, чтобы все функции были реализованы в одном бинарнике интерпретатора?
0
Спасибо за комментарий, настолько глубоко я не копал. Но то, что реализация оставляет желать лучшего — это факт. Даже с банальным вебом проблема — у нас на сервере вывод буферизируется в перловую переменную, неловкое движение с флагом — и кусок страницы испорчен. Да и вообще неудобно. Но наверное это лучше чем совсем ничего. Ждем perl6, там вроде обещали полноценный strict utf зашитый по самое нехочу.
0
Как на Javascript подсчитать md5/sha1 сумму от не-ASCII файла?
0
Хорошая статья.Спасибо. Только вот на PERL я практически не программирую. Написал бы ктонибудь подобную по php ато даже mb_string не во всех случаях помогает.
-4
UFO just landed and posted this here
Почему погода показывается только для Москвы?
GeoIP отменили? Сделали хотя бы выбор города — ведь и того нет.
GeoIP отменили? Сделали хотя бы выбор города — ведь и того нет.
0
UFO just landed and posted this here
Было бы неплохо, если бы хоть кто-нибудь объяснил, зачем нам PHP :)
Этот блог посвящен именно перлу, Ваш вопрос здесь выглядит несколько странно.
Этот блог посвящен именно перлу, Ваш вопрос здесь выглядит несколько странно.
+1
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 у меня желание пропало. Когда будет нечего делать, лучше питон поковыряю :)
+1
UFO just landed and posted this here
Ну не совсем соглашусь. Для МАЛЕНЬКИХ веб-задач, действительно, выбор CGI Perl или PHP — вопрос предпочтения, и они похожи. А вот когда дело доходит до проектов с большим объемом кода и высокими нагрузками, то выбор встает не совсем между Perl и PHP, а скорее между mod_perl и PHP (или между FastCGI Perl и PHP). Названия похожи, а вот методики разработки и архитектура очень сильно различны.
0
Отличная статья, единственно, я бы убрал термин «wide characters» из параграфа под «The Perl Way», поскольку в мире статических-компиляторов под ним чаще всего понимаются элементы UTF-16/UCS2, а в perl-мире это только путает. Есть только байты и символы (числа от 0 до 2^32-1 на 32-битных платформах).
0
Отлично написано, keep it up!
0
Очень-очень напоминает мой (Mons Anderson) доклад, особенно в части примеров кода.
Либо мы очень сходно мыслим, либо кто-то случайно забыл указать используемые источники ;)
Либо мы очень сходно мыслим, либо кто-то случайно забыл указать используемые источники ;)
+1
ты б дал ссылочку на презенташку свою с докладом или на текстовый его вариант, если таки написал уже +)
0
Ну презенташка — не вопрос.
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
+2
Статья писалась полностью из головы. Единственный действительно придуманный пример кода приведен в разделе «грабли», остальные естественным образом взяты из перлдоков, список которых приведен в конце статьи ;-)
А где можно посмотреть на доклад? Если он на эту же тему, я просто прицеплю его в конце статьи, читатели будут только рады.
А где можно посмотреть на доклад? Если он на эту же тему, я просто прицеплю его в конце статьи, читатели будут только рады.
0
А что с юникодом в 6-й версии планируется?
0
Топорное решение, без модулей:
%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;
(добавил к паре слов...)
-1
Sign up to leave a comment.
Пара слов про UTF-8