Как стать автором
Обновить

Комментарии 53

О!) Что именно всё же значит — Wide characters in print и как это эффективно бороть, не зная заранее с какой кодировкой работаешь?=)
Значит, что в файловый дескриптор напечатаны данные с UTF-флагом. Вариантов куча, есть правильные, есть удобные.
0) Идеальное решение — сделать так, чтобы данные всегда были в одном единственном формате.
1) no warnings 'layer' — самый эффективный способ избавиться от варнингов :)
2) при помощи open или binmode укажите адекватную кодировку для файлового дескриптора. open подойдет для открываемых Вами файлов, binmode — для уже открытых дескрипторов типа STDOUT. Тут может возникнуть конфуз, если на печать пойдут обычные байты, без флага — данные покоцает.
3) ручками следите за тем, что печатаете, и при необходимости опускайте флажок
А если речь идёт не о файле, а о получаемых «извне» — в данном случае — из интернета «скалярах»?)

Я нашёл модуль Фитцпатрика — is_utf8 — и мы экспериментировали с «шириной» символа — но эффективно побороть не удалось всё же(
НЛО прилетело и опубликовало эту надпись здесь
Угу. У нас все входные данные автоматически перекодируются из кодировки сайта в utf-форму, потом стараемся работать только с уникодом.
хм. То есть я правильно понимаю, что получаемая wide characters — это свидетельство флага юникода?
Да. Любое упоминание про wide characters это свидетельство уникода, причем с utf-флагом
Ну тогда получается, что бывает флаг юникода у получаемых откуда-то данных? Я же могу доверять своим глазам :)

Если конкретно — то через LWP получаемых=)
НЛО прилетело и опубликовало эту надпись здесь
OK, буду копать=)

Как что откопаю — отпишу :)

Спасибо за консультацию=)
НЛО прилетело и опубликовало эту надпись здесь
Попробуйте сразу после получения данных (совсем сразу!!) проверить их функцией is_utf8. Уверен, флага не будет. Ну и ниже проверочки по коду раскидайте, особенно если Вы к переменной с результатами LWP что-либо конкатенируете (даже цифру или пустую строку).

Кстати о цифрах. Когда я впервые столкнулся с уникодом, мне нужно было вклеить результаты разбора 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).
Да, для тех, кто захочет копать. Ключевые слова: SWASH, SWASHGET, encoding.pm, utf8.pm, open.pm. (Кстати, мне никогда не нравилось называть «use utf8» и другие похожие штуки вроде «use strict» прагмой, потому что все «прагмы» на самом деле — обыкновенные модули на Perl. Как правило, они подменяют разные «плохо документированные» переменные типа $^W, которые влияют на результаты компиляции.)
Да, и еще: в 5.10 такая же история, как в 5.8. Ничего не изменилось.
Это даже хорошо, что не изменилось. Если бы они в очередной раз поменяли логику работы, как это было с 5.6, на него бы просто никто не перешел.
НЛО прилетело и опубликовало эту надпись здесь
В чём костыльность-то? Вы хотели, чтобы все функции были реализованы в одном бинарнике интерпретатора?
Спасибо за комментарий, настолько глубоко я не копал. Но то, что реализация оставляет желать лучшего — это факт. Даже с банальным вебом проблема — у нас на сервере вывод буферизируется в перловую переменную, неловкое движение с флагом — и кусок страницы испорчен. Да и вообще неудобно. Но наверное это лучше чем совсем ничего. Ждем perl6, там вроде обещали полноценный strict utf зашитый по самое нехочу.
Как на Javascript подсчитать md5/sha1 сумму от не-ASCII файла?
поправка: сериализовать в utf-8 и подсчитать…
Хорошая статья.Спасибо. Только вот на PERL я практически не программирую. Написал бы ктонибудь подобную по php ато даже mb_string не во всех случаях помогает.
НЛО прилетело и опубликовало эту надпись здесь
Спасибо большое, добрый человек. Будем пробовать…
Почему погода показывается только для Москвы?
GeoIP отменили? Сделали хотя бы выбор города — ведь и того нет.
Упс. Не в том топике закомментил :-D
НЛО прилетело и опубликовало эту надпись здесь
Было бы неплохо, если бы хоть кто-нибудь объяснил, зачем нам PHP :)
Этот блог посвящен именно перлу, Ваш вопрос здесь выглядит несколько странно.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
А где вы здесь вычитали, что Perl достойнее PHP? :))
Хм, кажется я Вас не совсем понял вначале, сорри.

Выбор языка во многом субъективен. Одно дело, когда язык выбирается осмысленно под конкретную задачу — скажем, Perl принято хвалить за его возможности по работе со строками (которые последнее время можно найти в любом другом языке), C++ хвалят за скорость работы ну и т.д. Perl и PHP во многом похожи и под веб-задачу имхо можно пользоваться любым из них, в зависимости от предпочтений. Когда я знакомился с PHP, некоторые принятые там принципы, вроде подключения библиотек, встали мне поперек горла, и я этот язык оставил. Возможно, сейчас многое изменилось, но разбираться в PHP у меня желание пропало. Когда будет нечего делать, лучше питон поковыряю :)
НЛО прилетело и опубликовало эту надпись здесь
Ну не совсем соглашусь. Для МАЛЕНЬКИХ веб-задач, действительно, выбор 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-битных платформах).
Спасибо. Совсем убирать этот текст мне бы не хотелось, т.к. некоторое количество выдаваемых Perl варнингов связано именно с этим термином. Пожалуй, придется прокомментировать.
Отлично написано, keep it up!
Очень-очень напоминает мой (Mons Anderson) доклад, особенно в части примеров кода.
Либо мы очень сходно мыслим, либо кто-то случайно забыл указать используемые источники ;)
ты б дал ссылочку на презенташку свою с докладом или на текстовый его вариант, если таки написал уже +)
Ну презенташка — не вопрос.
taka.xfo.cc/utf8.xul
А вот статью так и не выложил
т.е. есть она только в том спецвыпуске «Сетевых решений», который был сделан к By Perl
www.nestor.minsk.by/sr/2008/09/sr80902.html
Статья писалась полностью из головы. Единственный действительно придуманный пример кода приведен в разделе «грабли», остальные естественным образом взяты из перлдоков, список которых приведен в конце статьи ;-)

А где можно посмотреть на доклад? Если он на эту же тему, я просто прицеплю его в конце статьи, читатели будут только рады.
* прицеплю ссылку на него
Прицепил, спасибо. Имхо не так уж и похоже ;), у Вас более практическая вещь получилась. Пишите теперь сюда :)
А что с юникодом в 6-й версии планируется?
Планируется хорошо. В реальности — зависит от реализации.
Судя по perl6.ru/unicode/ даже слишком хорошо.

На самом деле всё ещё лучше :)

<bacek> std: sub prefix:<Σ> (*@args) {...}; my @a; say Σ@a
<p6eval> std 25806: OUTPUT«ok 00:03 41m␤»

Топорное решение, без модулей:

%unicode = (
"%u0430" => «а», "%u0431" => «б», "%u0432" => «в»,
"%u0433" => «г», "%u0434" => «д», "%u0435" => «е»,

);

$query_value =~ s/(%u[0-9A-F]{4})/$unicode{$1}/eg;

(добавил к паре слов...)
Вы — молодец
У меня проблема с расшифровкой строки из URL набранной в браузере кириллицей писал о ней еще давно тут.
У меня нет под рукой FF2, чтобы проверить гипотезу, но вообще при отправке запроса браузер отсылает хедер «Accept-Charset». Для моего FF3 она начинается с 1251, потом идет utf-8. Предполагаю, что если строка не распозналась как utf-8, мозилла использует первую кодировку, которая была в хедере.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации