Size: a a a

2021 January 21

AP

Anton Petrusevich in Modern::Perl
Оправдать можно многое
источник

VO

Vyacheslav Olkhovche... in Modern::Perl
ну вот оправдайте то, что pack транслирует флаг utf8 на выход
источник

VO

Vyacheslav Olkhovche... in Modern::Perl
Stas Raskumandrin
вот самая лучшая статья по юникоду, которую встречал, и которая, к сожалению, осталась только на веб-архиве:
https://web.archive.org/web/20200215211621/http://www.nestor.minsk.by/sr/2008/09/sr80902.html
она кстати уже устарела как минимум в нескольких местах
источник

a

allter in Modern::Perl
Anton Petrusevich
Оправдать можно многое
Я уже писал что на мой взгляд задним умом было бы правильно сделать несовместимыми байты и строки (по крайней мере по умолчанию, без дополнительных прагм). Но сделали как сделали.
источник

VG

Vadim Goncharov in Modern::Perl
Anton Petrusevich
вот, например, мне было неожиданно узнать, что риддир возвращает бинарные строки...
всё правильно, это ведь такой же внешний мир по отношению к нашему процессу
источник

SZ

Sergey Zhmylove in Modern::Perl
Vyacheslav Olkhovchenkov
ну вот оправдайте то, что pack транслирует флаг utf8 на выход
А ман почитать?
источник

SZ

Sergey Zhmylove in Modern::Perl
И да, всё не так позитивно:
источник

VO

Vyacheslav Olkhovche... in Modern::Perl
ну возможно я его читал мимо строк, так что давай цитату
источник

SZ

Sergey Zhmylove in Modern::Perl
@PerlBanjoBot $ perl -CSD -e 'print "\x{1f981}"' |hexdump -C ; perl -CSD -e 'print(pack("a", "\x{1f981}"))' |hexdump -C ; perl -le 'print utf8::is_utf8(pack("c", "\x{1f981}"))'
источник

P

PerlBanjoBot in Modern::Perl
Sergey Zhmylove
@PerlBanjoBot $ perl -CSD -e 'print "\x{1f981}"' |hexdump -C ; perl -CSD -e 'print(pack("a", "\x{1f981}"))' |hexdump -C ; perl -le 'print utf8::is_utf8(pack("c", "\x{1f981}"))'
00000000  f0 9f a6 81                                       |....|
00000004
00000000  f0 9f a6 81                                       |....|
00000004

https://PerlBanjo.com/9407064639
источник

SZ

Sergey Zhmylove in Modern::Perl
Ну и естественно:
источник

VG

Vadim Goncharov in Modern::Perl
PerlBanjoBot
00000000  f0 9f a6 81                                       |....|
00000004
00000000  f0 9f a6 81                                       |....|
00000004

https://PerlBanjo.com/9407064639
третья команда просралась?
источник

SZ

Sergey Zhmylove in Modern::Perl
@PerlBanjoBot $ perl -le 'print utf8::is_utf8(pack("a", "\x{1f981}"))'
источник

P

PerlBanjoBot in Modern::Perl
Sergey Zhmylove
@PerlBanjoBot $ perl -le 'print utf8::is_utf8(pack("a", "\x{1f981}"))'
источник

SZ

Sergey Zhmylove in Modern::Perl
Vadim Goncharov
третья команда просралась?
Нет, там ""
источник
2021 January 22

VO

Vyacheslav Olkhovche... in Modern::Perl
там пиздец еще больше -- в U0 режиме нельзя закодировать байт 0xee
источник

VO

Vyacheslav Olkhovche... in Modern::Perl
т.е. судя по всему pack производит именно строки, а не байты.
источник

AP

Anton Petrusevich in Modern::Perl
возможно, он просто не меняет флаг с того, что пришло
источник

OP

Oleg Pronin in Modern::Perl
Я заметил, что многие путаются в utf8 сильно и получают wide character или кракозябры (двойной энкод etc). Хотя тема на самом деле дико простая.
Все что нужно знать:
1) у перла строка может представлять 2 сущности - byte stream и string. is_utf8 говорит какой из режимов включен. В режиме строки просто некоторые функции (substr, lenght И так далее) меняют свой behaviour с побайтового на посимвольный, что занимает дополнительное процессорное время естественно, потому что в пасяти все равно utf8.
2) внутренее представление не изменяется никак при переходе из одного режима в другой. decode_utf8 не делает нихрена кроме как проверяет что там нет инвалидных последовательностей utf8 и переключает режим.
3) чтобы не запутаться где какой режим, простое правило - все что приходит извне (чтение из сокета, файла, stdin, ...) - всегда байтовое. Соответсвенно все что туда отправляется должно быть тоже (иначе будет wide character, однако изза совпадения внутреннего прдставления, все будет работать).
4) еще простое правило - функция is_utf8 за крайне редкими исключениями не должна использоваться. Вы всегда должны знать где у вас байты а где символы. Для этого как правило сразу на входе декодят и в приложении используются символы (кроме случая когда данные бинарные должны быть), и энкодятся в самом конце перед записью в канал.
5) некоторые библиотеки избавляют вас от необходимости энкодить и декодить. Например json::xs::decode_json() ожидает от вас бинарный поток и порождает структуру с символами. А на encode ожидает символы и порождает байты. Обычно это интуитивно логично и ожидаемо.
В случаи работы через обьект JSON::XS->new->utf8->
Метод utf8 как раз заставляет его порождать на декод и ожидать на энкод символы. Если его не писать то в структуре которую вернет декод будут тоже байты (лучше так не делать, только если точно уверены что там только инглиш). Но на вход декод и выход энкод всегда байты, это не меняется, иначе бессмыслица.
Еще например template toolkit аналогично, считывает с диска байты, декодит в символы, ожидает от вас переменные в символах, рендерит и энкодит в байты итоговый результат.
источник

OP

Oleg Pronin in Modern::Perl
6) многие считают что utf8 это символы. Нет. Это байты. Utf8 это способ сериализации кодов юникод, то есть бинарный режим. В перле вообще нет настоящего символьного режима. Он чисто виртуальный (выполняется в рантайме, разбирая каждый байт). Например когда строке в режиме символов говорят substr на 10й символ, перл не может херак и встать на 10й символ сразу как в бинарном режиме, ему придется линейно идти от начала строки отсчитывая символы из байтов.
Настоящий символьный режим был бы если бы перл представлял строку в памяти как utf32 - коды юникода (и памяти занимало бы в 2-4 раза больше, но работало бы быстрее). В перле в режиме символов всегда бинарный режим utf8 под капотом, и виртуальное рантайм эмуляция.
источник