[Kiev-pm] utf8
Denis Sokolovsky
ganellon at gmail.com
Fri Jan 17 05:43:11 PST 2014
Дозвольте не погодитись. По-перше я не бачив що б всюди рекомендували
Encode замість utf8::encode/decode - вони по різному працюють і не можуть
виключно заміщати одна одну. По-друге все залежить від мети. utf8::decode
більш строгий до корректності utf8 строки ніж Encode, який пробує створити
щось валідне будь-що. Натомість utf8::decode не вміє займатись
перекодовуванням з будь-чого в utf8. Ось простий приклад, що демострує
строгість utf8::decode:
$ perl -MEncode -MDevel::Peek -e '$x = "фів\321"; print "Original\n";
Dump($x); print "Encode/utf8\n"; Dump(Encode::decode("UTF-8", $x));
utf8::decode($x); Dump($x);'
Original
SV = PV(0x92f7750) at 0x9313f08
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x930f5b8 "\321\204\321\226\320\262\321"\0
CUR = 7
LEN = 12
Encode/utf8
SV = PV(0x92f7d60) at 0x93935d0
REFCNT = 1
FLAGS = (TEMP,POK,pPOK,UTF8)
PV = 0x939ae78 "\321\204\321\226\320\262\357\277\275"\0 [UTF8
"\x{444}\x{456}\x{432}\x{fffd}"]
CUR = 9
LEN = 12
SV = PV(0x92f7750) at 0x9313f08
REFCNT = 1
FLAGS = (POK,pPOK)
PV = 0x930f5b8 "\321\204\321\226\320\262\321"\0
CUR = 7
LEN = 12
Відповідно функція is_utf8 для результату Encode видає true, а після
utf8::decode строка так і не стала utf8. Я погоджуюсь що для більшості веб
задач варто все ж таки використовувати Encode (особливо коли мова
стосується данних від користувача) тому що вона майже наглухо fail-proof,
але то не є панацея.
2014/1/16 vti <viacheslav.t ÎÁ gmail.com>
> Не надо путать utf8::* с Encode::*. Везде рекомендуют использовать
> Encode, а не вручную проставлять utf8-флаги. Кроме того используя 'UTF-8' в
> Encode, вместо 'utf8', utf-символы кое-как, но валидируются.
>
>
> On 01/16/2014 03:47 PM, Denis Sokolovsky wrote:
>
> Вставлю і я свої 5 копійок: utf8::encode/decode нічого не перекодовують,
> а просто помічають скаляр як такий що містить не байти, а символи. Це
> дозволяє perl відповідно працювати з такими скалярами. Може такий приклад
> трохи прояснить ситуацію:
>
> $ perl -MDevel::Peek -e '$x = "фів"; Dump($x); utf8::decode($x); Dump($x)'
>
> SV = PV(0x1ceed80) at 0x1d0d4b8
>
> REFCNT = 1
>
> FLAGS = (POK,pPOK)
>
> PV = 0x1cfc5e0 "\321\204\321\226\320\262"\0
>
> CUR = 6
>
> LEN = 16
>
> SV = PV(0x1ceed80) at 0x1d0d4b8
>
> REFCNT = 1
>
> FLAGS = (POK,pPOK,UTF8)
>
> PV = 0x1cfc5e0 "\321\204\321\226\320\262"\0 [UTF8
> "\x{444}\x{456}\x{432}"]
>
> CUR = 6
>
> LEN = 16
>
>
> Відповідно ці функції відмінно лягають в процес описаний Турським: на
> вході для отримання з байтів символів викоикаємо decode, на виході для того
> щоб віддавати байти: encode. Додаткові опції, назразок того самого :utf8
> для open просто автоматизують данну операцію.
>
> --
> Denis Sokolovsky
> On Jan 16, 2014 3:24 PM, "vti" <viacheslav.t ÎÁ gmail.com> wrote:
>
>> On 01/16/2014 03:09 PM, my.yarnik ÎÁ yandex.ru wrote:
>>
>>> Во-первых, лучше использовать use utf8; вместо use encoding 'utf8';,
>>>> т.к.
>>>> согласно http://perldoc.perl.org/encoding.html
>>>> данная прагма в 5.18+ является deprecated.
>>>>
>>> Спасибо
>>>
>>> use open qw/:std :utf8/;
>>>> use utf8;
>>>> use CGI qw/:standard -utf8/;
>>>>
>>> Вот как раз если добавлять :std, то ломаются данные из простой формы
>>> на данный момент рабочий вариант вот такой:
>>>
>>> use open qw/:utf8/;
>>> use utf8;
>>> use CGI qw/:standard -utf8/;
>>>
>>> Но у него есть мелкий недостаток, он не правильно выводит русское
>>> название
>>> файла при glob("*").
>>> Можно конечно использовать костыль, предложенный vti, в виде
>>> Encode::decode('UTF-8', $_);
>>> Тем более, что русских файлов в принципе не желательно держать.
>>>
>>> Для тех кто хочет потестить (посмотреть):
>>> Пожалуйста http://www.ahost.com.ua/utf8/index.cgi
>>> FTP: admin_utf8 / utf8
>>> http://77.120.116.161/myadmin admin_utf8 / utf8
>>>
>>
>> Перекодировка -- это не костыль. Процитирую свои изменения в тот файл:
>>
>> Рекомендации по UTF-8:
>> 1. print должен быть в UTF-8: binmode(STDOUT, ":utf8");
>> 2. glob возвращает файл в байтах, необходимо преобразовать в UTF-8: my
>> $file = Encode::decode('UTF-8', $_);
>> 3. при открытии файла необходимо сообщить, что мы хотим автоматически
>> UTF-8: open(FILE, '<:encoding(UTF-8)', "$file");
>> 4. вместо use encoding 'utf-8' использовать use utf8; и только тогда,
>> когда в исходном тексте программы есть UTF-8 символы (в данном случае
>> есть)
>> 5. с базой вижу есть вариант правильный (set names + mysql_enable_utf8),
>> надеюсь, что и в схеме стоит кодировка UTF-8 (иначе будет каша потом)
>>
>> Сократить этот список можно используя utf8::all.
>> _______________________________________________
>> Kiev-pm mailing list
>> Kiev-pm ÎÁ pm.org
>> http://mail.pm.org/mailman/listinfo/kiev-pm
>>
>
>
> _______________________________________________
> Kiev-pm mailing listKiev-pm ÎÁ pm.orghttp://mail.pm.org/mailman/listinfo/kiev-pm
>
>
>
> _______________________________________________
> Kiev-pm mailing list
> Kiev-pm ÎÁ pm.org
> http://mail.pm.org/mailman/listinfo/kiev-pm
>
>
--
Denis Sokolovsky
----------- ���� ���-----------
÷ÌÏÖÅÎÉÅ × ÆÏÒÍÁÔÅ HTML ÂÙÌÏ ÉÚ×ÌÅÞÅÎÏ…
URL: <http://mail.pm.org/pipermail/kiev-pm/attachments/20140117/014259b4/attachment-0001.html>
More information about the Kiev-pm
mailing list