Почему современный Perl по умолчанию избегает UTF-8?

557

Интересно, почему большинство современных решений, построенных с использованием Perl, не поддерживают UTF-8? по умолчанию .

Я понимаю, что для основных скриптов Perl существует много проблем, которые могут сломать вещи. Но, с моей точки зрения, в 21 - м веке, большие новые проекты (или проекты с большой перспективой) должны сделать их программное обеспечение UTF-8 доказательство с нуля. Тем не менее я не вижу, что это происходит. Например, Moose разрешает строгие и предупреждения, но не Unicode . Modern :: Perl также уменьшает шаблон, но не обрабатывает UTF-8.

Почему? Есть ли причины избегать использования UTF-8 в современных проектах Perl в 2011 году?


Комментировать @tchrist слишком долго, поэтому я добавляю его сюда.

Кажется, я не прояснил себя. Позвольте мне попытаться добавить некоторые вещи.

Мы с Тристом видим ситуацию примерно одинаково, но наши выводы полностью противоположны. Я согласен, ситуация с Unicode сложная, но именно поэтому нам (пользователям и программистам Perl) нужен какой-то слой (или прагма), который делает обработку UTF-8 настолько простой, насколько это должно быть в наши дни.

Чрист указал на многие аспекты, которые я хочу охватить, я буду читать и думать о них в течение нескольких дней или даже недель. Тем не менее, это не моя точка зрения. Чрист пытается доказать, что не существует единственного способа «включить UTF-8». У меня не так много знаний, чтобы спорить с этим. Итак, я придерживаюсь живых примеров.

Я играл с Rakudo и UTF-8 был там как мне было нужно . У меня не было никаких проблем, это просто сработало. Может быть, есть некоторые ограничения где-то глубже, но в начале все, что я тестировал, работало так, как я ожидал.

Разве это не должно быть целью и в современном Perl 5? Я подчеркиваю это больше: я не предлагаю UTF-8 , как набор символов по умолчанию для ядра Perl, я предлагаю возможность вызвать его с помощью оснастки для тех , кто разрабатывает новые проекты.

Еще один пример, но с более негативным тоном. Фреймворки должны облегчить разработку. Несколько лет назад я попробовал веб-фреймворки, но просто выбросил их, потому что «включение UTF-8» было настолько неясным. Я не нашел, как и где подключить поддержку Unicode. Это было так много времени, что мне было легче идти по старому пути. Теперь я увидел, что здесь есть щедрость для решения той же проблемы с Mason 2: Как сделать Mason2 UTF-8 чистым? , Итак, это довольно новый фреймворк, но для его использования с UTF-8 требуется глубокое знание его внутренних возможностей. Это как большой красный знак: СТОП, не используйте меня!

Мне очень нравится Perl. Но иметь дело с Юникодом больно. Я все еще бегаю по стенам. В некотором смысле tchrist прав и отвечает на мои вопросы: новые проекты не привлекают UTF-8, потому что это слишком сложно в Perl 5.

неделя
источник
15
Извините, но я согласен с @tchrist - UTF-8 чрезвычайно сложен. Нет фреймворка или инструмента, который просто «щелкает выключателем», а затем обрабатывает его правильно. Это то, о чем вы должны подумать непосредственно при разработке приложения, а не то, что любой вид фреймворка или языка может вам помочь. Если Ракудо только что сработал для вас, вы не были достаточно предприимчивы с вашими контрольными случаями - так как тогда потребуется несколько примеров из ответа @ tchrist и мясника.
Билли ОНил
12
Что именно вы надеетесь сделать Moose или Modern :: Perl? Волшебным образом снова сделать случайно закодированные символьные данные в файлах и базах данных в правильные данные?
jrockway
13
Что это обозначает? Лось не имеет ничего общего с манипулированием текстом. Почему он должен знать о кодировке символов, а тем более выбрать для себя кодировку по умолчанию? (Во всяком случае, причина, по которой перечисленные вами прагмы не затрагивают кодировку, заключается в том, что для прагм Perl существует соглашение о влиянии на лексическое поведение. Предполагая, что весь мир, включая другие модули, является UTF-8, является просто неправильным решением. Это не PHP или Ruby здесь.)
jrockway
8
(Также ... «большинство современных Perl-приложений» ломаются на UTF-8? Я, конечно, никогда не писал приложения, Perl или иное, не поддерживающее Unicode.)
jrockway
11
В северном направлении tchrist (Том Кристиансен) опубликовал свой [ training.perl.com/OSCON2011/index.html Материалы Тома Кристиансена для OSCON 2011] о Unicode. В статье под названием «Перестрелка поддержки Юникода: хорошее, плохое и (в основном) уродливое» говорится о поддержке Unicode в разных языках программирования. Только Google Go и Perl5 поддерживают полный Unicode, только встроенный Google Go (без упоминания о Perl6).
Якуб Наребски

Ответы:

1146

: 𝟕 𝘿𝙞𝙨𝙘𝙧𝙚𝙩𝙚 𝙍𝙚𝙘𝙤𝙢𝙢𝙚𝙣𝙙𝙖𝙩𝙞𝙤𝙣𝙨

  1. Установите ваш PERL_UNICODEenvariable в AS. Это делает все сценарии Perl декодируемыми @ARGVкак строки UTF ‑ 8 и устанавливает кодировку всех трех параметров stdin, stdout и stderr в UTF ‑ 8. И то, и другое - глобальные, а не лексические последствия.

  2. В верхней части исходного файла (программа, модуль, библиотека, dohickey) явно утверждают, что вы используете Perl версии 5.12 или выше, используя:

    use v5.12;  # minimal for unicode string feature
    use v5.14;  # optimal for unicode string feature
  3. Включите предупреждения, поскольку предыдущее объявление включает только ограничения и функции, а не предупреждения. Я также предлагаю превратить предупреждения Unicode в исключения, поэтому используйте обе эти строки, а не одну из них. Однако обратите внимание , что при v5.14, то utf8класс предупреждения включает в себя три других subwarnings , которые все могут быть отдельно включены: nonchar, surrogate, и non_unicode. Этим вы, возможно, захотите осуществлять больший контроль.

    use warnings;
    use warnings qw( FATAL utf8 );
  4. Объявите, что этот источник кодируется как UTF ‑ 8. Хотя когда-то давно эта прагма делала другие вещи, теперь она служит одной единственной цели, а не другим:

    use utf8;
  5. Объявите, что все, что открывает файловый дескриптор в этой лексической области, но не где-либо еще, означает, что этот поток закодирован в UTF-8, если вы не укажете иначе. Таким образом, вы не влияете на код другого модуля или другой программы.

    use open qw( :encoding(UTF-8) :std );
  6. Включить именованные символы через \N{CHARNAME}.

    use charnames qw( :full :short );
  7. Если у вас есть DATAдескриптор, вы должны явно установить его кодировку. Если вы хотите, чтобы это был UTF ‑ 8, то скажите:

    binmode(DATA, ":encoding(UTF-8)");

Конечно, нет конца другим вопросам, которые могут в конечном итоге вас заинтересовать, но их будет достаточно, чтобы приблизиться к государственной цели «заставить все просто работать с UTF-8», хотя и для несколько ослабленного смысла этих терминов.

Еще одна прагма, хотя она не связана с Unicode, это:

      use autodie;

Настоятельно рекомендуется.

🌴 🐪🐫🐪 🌞 𝕲𝖔 𝕿𝖍𝖔𝖚 𝖆𝖓𝖉 𝕯𝖔 𝕷𝖎𝖐𝖊𝖜𝖎𝖘𝖊 🌞 🐪🐫🐪 🐁


🎁 🐪 𝕭𝖔𝖎𝖑𝖊𝖗⸗𝖕𝖑𝖆𝖙𝖊 𝖋𝖔𝖗 𝖀𝖓𝖎𝖈𝖔𝖉𝖊⸗𝕬𝖜𝖆𝖗𝖊 𝕮𝖔𝖉𝖊 🐪 🎁


Мой собственный шаблон в эти дни имеет тенденцию выглядеть следующим образом:

use 5.014;

use utf8;
use strict;
use autodie;
use warnings; 
use warnings    qw< FATAL  utf8     >;
use open        qw< :std  :utf8     >;
use charnames   qw< :full >;
use feature     qw< unicode_strings >;

use File::Basename      qw< basename >;
use Carp                qw< carp croak confess cluck >;
use Encode              qw< encode decode >;
use Unicode::Normalize  qw< NFD NFC >;

END { close STDOUT }

if (grep /\P{ASCII}/ => @ARGV) { 
   @ARGV = map { decode("UTF-8", $_) } @ARGV;
}

$0 = basename($0);  # shorter messages
$| = 1;

binmode(DATA, ":utf8");

# give a full stack dump on any untrapped exceptions
local $SIG{__DIE__} = sub {
    confess "Uncaught exception: @_" unless $^S;
};

# now promote run-time warnings into stack-dumped
#   exceptions *unless* we're in an try block, in
#   which case just cluck the stack dump instead
local $SIG{__WARN__} = sub {
    if ($^S) { cluck   "Trapped warning: @_" } 
    else     { confess "Deadly warning: @_"  }
};

while (<>)  {
    chomp;
    $_ = NFD($_);
    ...
} continue {
    say NFC($_);
}

__END__

🎅 𝕹 𝖔 𝕸 𝖆 𝖌 𝖎 𝖈 𝕭 𝖚 𝖑 𝖑 𝖊 𝖙 🎅


Сказать, что «Perl должен [ как-то! ] включить Unicode по умолчанию »даже не задумывалась о том, чтобы обойтись, говоря достаточно для того, чтобы быть хоть немного полезной в каком-то редком и изолированном случае. Юникод - это намного больше, чем просто большой репертуар персонажей; Кроме того, все эти персонажи взаимодействуют по-разному.

Даже простейшие минимальные меры, которые (некоторые) люди думают, что они хотят, гарантированно сокрушат миллионы строк кода, кода, который не имеет шансов «обновить» до вашего изящного нового модного мира Brave New World .

Это намного сложнее, чем люди притворяются. Я много думал об этом за последние несколько лет. Я хотел бы, чтобы мне показали, что я не прав. Но я так не думаю. Юникод существенно сложнее, чем модель, которую вы хотели бы навязать ему, и здесь есть сложность, которую вы никогда не сможете заметить. Если вы попытаетесь, вы сломаете либо свой собственный, либо чужой код. В какой-то момент вы просто должны сломаться и узнать, что такое Unicode. Вы не можете притворяться, что это то, чем это не является.

🐪 делает все возможное, чтобы упростить Unicode, гораздо больше, чем все, что я когда-либо использовал. Если вы думаете, что это плохо, попробуйте что-нибудь другое на некоторое время. Затем вернитесь к 🐪: либо вы вернетесь в лучший мир, либо вы принесете то же самое с собой, чтобы мы могли использовать ваши новые знания, чтобы улучшить these в этих вещах.


💡 𝕴𝖉𝖊𝖆𝖘 𝖋𝖔𝖗 𝖆 𝖀𝖓𝖎𝖈𝖔𝖉𝖊 ⸗ 𝕬𝖜𝖆𝖗𝖊 🐪 𝕷𝖆𝖚𝖓𝖉𝖗𝖞 𝕷𝖎𝖘𝖙 💡


Как минимум, вот некоторые вещи, которые могут потребоваться для того, чтобы enable «включить Юникод по умолчанию», как вы выразились:

  1. Все 🐪 исходный код должен быть в UTF-8 по умолчанию. Вы можете получить это с помощью use utf8или export PERL5OPTS=-Mutf8.

  2. DATAРучка 🐪 должна быть UTF-8. Вы должны будете сделать это на основе пакета, как в binmode(DATA, ":encoding(UTF-8)").

  3. Программные аргументы скриптов 🐪 следует понимать как UTF-8 по умолчанию. export PERL_UNICODE=Aили perl -CA, или export PERL5OPTS=-CA.

  4. Стандартные потоки ввода, вывода и ошибок должны по умолчанию использовать UTF-8. export PERL_UNICODE=Sдля всех из них, или I, Oи / или Eтолько для некоторых из них. Это как perl -CS.

  5. Любые другие дескрипторы, открытые 🐪, должны рассматриваться как UTF-8, если не указано иное; export PERL_UNICODE=Dили с iи oдля определенных из них; export PERL5OPTS=-CDдолжно сработать. Это делает -CSADдля всех них.

  6. Покройте обе базы плюс все потоки, которые вы открываете export PERL5OPTS=-Mopen=:utf8,:std. Смотрите Uniquote .

  7. Вы не хотите пропустить ошибки кодирования UTF-8. Попробуй export PERL5OPTS=-Mwarnings=FATAL,utf8. И убедитесь, что ваши входные потоки всегда binmoded :encoding(UTF-8), а не только :utf8.

  8. Кодовые точки между 128–255 следует понимать как the как соответствующие кодовые точки Unicode, а не просто незаполненные двоичные значения. use feature "unicode_strings"или export PERL5OPTS=-Mfeature=unicode_strings. Это сделает uc("\xDF") eq "SS"и "\xE9" =~ /\w/. Простое export PERL5OPTS=-Mv5.12или лучшее также получит это.

  9. Именованные символы Юникода по умолчанию не включены, поэтому добавьте export PERL5OPTS=-Mcharnames=:full,:short,latin,greekили некоторые другие. Смотрите Uninames и tcgrep .

  10. Вам почти всегда нужен доступ к функциям из стандартного Unicode::Normalizeмодуля различных типов разложений. export PERL5OPTS=-MUnicode::Normalize=NFD,NFKD,NFC,NFKD, а затем всегда запускать входящий материал через NFD и исходящий материал из NFC. Там нет I / O слоя для них еще , что я знаю, но вижу НКА , NFD , nfkd и NFKC .

  11. Сравнение строк в 🐪 используя eq, ne, lc, cmp, sort, и с & куб.см всегда неправы. Так что вместо @a = sort @b, вам нужно @a = Unicode::Collate->new->sort(@b). Можно также добавить это к вашему export PERL5OPTS=-MUnicode::Collate. Вы можете кэшировать ключ для бинарных сравнений.

  12. 🐪 встроенные модули любят printfи writeделают неправильные вещи с данными Unicode. Вы должны использовать в Unicode::GCStringмодуль для первого, и как то, что и также модуль , а для последнего. Смотрите UWC и Unifmt .Unicode::LineBreak

  13. Если вы хотите, чтобы посчитать как целые числа, то вы будете иметь , чтобы запустить свои \d+снимки с помощью в Unicode::UCD::numфункции , потому что 🐪 построен в atoi (3) в настоящее время не достаточно умен.

  14. У вас будут проблемы с файловой системой на 👽 файловых системах. Некоторые файловые системы молча принудительно преобразуют в NFC; другие молча предписывают переход в NFD. А другие еще что-то делают. Некоторые даже полностью игнорируют этот вопрос, что приводит к еще большим проблемам. Таким образом, вы должны сделать свою собственную обработку NFC / NFD, чтобы оставаться в здравом уме.

  15. Все ваши 🐪 код с участием a-zили A-Zи такие должны быть изменены , в том числе m//, s///и tr///. Это должно выделяться как кричащий красный флаг, что ваш код не работает. Но не ясно, как это должно измениться. Получить правильные свойства и понять их падеж сложнее, чем вы думаете. Я использую unichars и uniprops каждый день.

  16. Код, который использует \p{Lu}почти так же, как и код, который использует [A-Za-z]. Вы должны использовать \p{Upper}вместо этого, и знать причину, почему. Да \p{Lowercase}и \p{Lower}отличаются от \p{Ll}а \p{Lowercase_Letter}.

  17. Код, который использует [a-zA-Z]еще хуже. И это не может использовать \pLили \p{Letter}; это нужно использовать \p{Alphabetic}. Знаете, не все алфавиты - это буквы.

  18. Если вы ищете 🐪 переменных с /[\$\@\%]\w+/, то у вас есть проблема. Вы должны искать /[\$\@\%]\p{IDS}\p{IDC}*/, и даже это не думает о переменных пунктуации или переменных пакета.

  19. Если вы проверяете наличие пробелов, то вам следует выбирать между \hи \v, в зависимости. И вы никогда не должны использовать \s, так как это не значит [\h\v] , вопреки распространенному мнению.

  20. Если вы используете \nдля границы линии или даже \r\n, то вы делаете это неправильно. Вы должны использовать \R, что не то же самое!

  21. Если вы не знаете, когда и нужно ли вызывать Unicode :: Stringprep , вам лучше научиться.

  22. Сравнения без учета регистра должны проверять, являются ли две вещи одинаковыми буквами, независимо от их диакритики и тому подобного. Самый простой способ сделать это - использовать стандартный модуль Unicode :: Collate . Unicode::Collate->new(level => 1)->cmp($a, $b), Есть также eqметоды и такие, и вы , вероятно , следует узнать о matchи substrметоды тоже. Они имеют явные преимущества по сравнению со встроенными модулями.

  23. Иногда этого все еще недостаточно, и вместо этого вам нужен модуль Unicode :: Collate :: Locale , как Unicode::Collate::Locale->new(locale => "de__phonebook", level => 1)->cmp($a, $b)вместо этого. Считайте, что Unicode::Collate::->new(level => 1)->eq("d", "ð")это правда, но Unicode::Collate::Locale->new(locale=>"is",level => 1)->eq("d", " ð")это ложь. Точно так же, «ae» и «are», eqесли вы не используете локали, или если вы используете английский, но они отличаются в исландской локали. Что теперь? Это сложно, говорю тебе. Вы можете поиграть с ucsort, чтобы проверить некоторые из этих вещей.

  24. Рассмотрим, как сопоставить шаблон CVCV (согласный, гласный, согласный, гласный) в строке « niño ». Его форма NFD, которую вы, черт побери, лучше запомнили, чтобы вставить ее, становится «nin \ x {303} o». Теперь, что ты собираешься делать? Даже притворяясь, что гласная есть [aeiou](что, кстати, неправильно), вы не сможете сделать что-то подобное (?=[aeiou])\X), потому что даже в NFD кодовая точка, такая как «ø» , не разлагается ! Тем не менее, он будет проверяться равным «о», используя сравнение UCA, которое я только что показал вам. Вы не можете полагаться на НФД, вы должны полагаться на УЦА.


💩 𝔸 𝕤 𝕤 𝕦 𝕞 𝕖 𝔹 𝕣 𝕜 𝕖 𝕖 𝕟 𝕖 𝕖 𝕤 💩 💩


И это еще не все. Есть миллион ошибочных предположений о Unicode. Пока они не поймут эти вещи, их код будет нарушен.

  1. Код, который предполагает, что он может открыть текстовый файл без указания кодировки, поврежден.

  2. Код, который предполагает кодировку по умолчанию, является неким родным кодированием платформы.

  3. Код, предполагающий, что веб-страницы на японском или китайском языке занимают меньше места в UTF-16, чем в UTF-8, неверен.

  4. Код, который предполагает, что Perl использует UTF-8 внутри, неверен.

  5. Код, который предполагает, что ошибки кодирования всегда будут вызывать исключение, неверен.

  6. Код, который предполагает, что кодовые точки Perl ограничены 0x10_FFFF, неверен.

  7. Код, который предполагает, что вы можете установить $/что-то, что будет работать с любым допустимым разделителем строк, неверен.

  8. Код, который предполагает равенство в обоих направлениях при сложении слов, как lc(uc($s)) eq $sили uc(lc($s)) eq $s, полностью нарушен и неверен. Учтите , что uc("σ")и uc("ς") оба "Σ", но lc("Σ")не может вернуться и тех.

  9. Код, который предполагает, что каждая строчная кодовая точка имеет отдельную заглавную или наоборот, не работает. Например, "ª"строчная буква без прописных букв; тогда как оба "ᵃ"и "ᴬ"являются буквами, но они не строчные буквы; однако они оба являются строчными кодами без соответствующих заглавных версий. Понял? Они не \p{Lowercase_Letter} , несмотря на то , как \p{Letter}и \p{Lowercase}.

  10. Код, который предполагает изменение регистра, не меняет длину строки.

  11. Код, который предполагает, что есть только два случая, нарушен. Там также заглавные буквы.

  12. Код, который предполагает, что только буквы имеют регистр, не работает. Оказывается, что помимо букв, цифры, символы и даже метки имеют регистр. На самом деле, изменение дела может даже заставить что-то изменить его основную общую категорию, например, \p{Mark}превращение в \p{Letter}. Это также может заставить его переключаться с одного сценария на другой.

  13. Код, который предполагает, что регистр никогда не зависит от локали, нарушается.

  14. Код, который предполагает, что Unicode дает представление о языковых стандартах POSIX, не работает.

  15. Код, предполагающий, что вы можете удалить диакритические знаки, чтобы получить базовые буквы ASCII, является злом, все же сломанным, поврежденным мозгом, неправильным и оправданием для смертной казни.

  16. Код, предполагающий, что диакритические знаки \p{Diacritic}и знаки \p{Mark}- это одно и то же, нарушается.

  17. Код, который предполагает \p{GC=Dash_Punctuation}покрытие столько, сколько \p{Dash}сломан.

  18. Код, который предполагает тире, дефисы и минусы - это то же самое, что и друг друга, или то, что существует только один из них, является ошибочным и неправильным.

  19. Код, который предполагает, что каждая кодовая точка занимает не более одного столбца печати, поврежден.

  20. Код, который предполагает, что все \p{Mark}символы занимают нулевые столбцы печати, не работает.

  21. Код, который предполагает, что символы, которые похожи друг на друга , похожи, сломан.

  22. Код, который предполагает, что символы, которые не похожи друг на друга, не похожи, нарушается.

  23. Код, который предполагает, что существует ограничение на количество кодовых точек в строке, которое \Xможет соответствовать только один , неверно.

  24. Код, который предполагает, что \Xникогда не может начинаться с \p{Mark}символа, неверен.

  25. Код, который предполагает, что \Xникогда не может содержать два не- \p{Mark}символа, неверен.

  26. Код, который предполагает, что он не может использовать "\x{FFFF}", неверен.

  27. Код, предполагающий кодовую точку, отличную от BMP, для которой требуются две кодовые единицы UTF-16 (суррогатные), будет кодироваться в два отдельных символа UTF-8, по одному на кодовую единицу, является неправильным. Это не так: он кодирует в одну кодовую точку.

  28. Код, который транскодирует из UTF-16 или UTF-32 с ведущими спецификациями в UTF-8, прерывается, если он помещает спецификацию в начало результирующего UTF-8. Это так глупо, инженер должен убрать веки.

  29. Код, который предполагает, что CESU-8 является допустимой кодировкой UTF, неверен. Аналогично, код, который думает, что кодировка U + 0000 как "\xC0\x80"UTF-8 не работает и ошибочна. Эти парни также заслуживают лечения век.

  30. Код, который предполагает, что символы, такие как >всегда, указывает на правое и <всегда указывает на левое неверно - потому что на самом деле это не так.

  31. Код, который предполагает, что если вы сначала выводите символ, Xа затем символ Y, то они будут отображаться как XYнеправильные. Иногда они этого не делают.

  32. Код, который предполагает, что ASCII достаточно хорош для правильного написания английского, глуп, недальновиден, неграмотен, сломлен, злой и неправильный. Долой их головы! Если это кажется слишком экстремальным, мы можем пойти на компромисс: отныне они могут печатать только большим пальцем ноги от одной ноги. (Остальные будут приклеены.)

  33. Код, который предполагает, что все \p{Math}кодовые точки являются видимыми символами, неверен.

  34. Код, который предполагает, \wсодержит только буквы, цифры и подчеркивания, является неправильным.

  35. Код, который предполагает, что ^и ~является знаками препинания, является неправильным.

  36. Код, который предполагает üумлаут, неверен.

  37. Код, который считает, что такие вещи, как содержат какие-либо буквы в них, является неправильным.

  38. Кодекс, который считает \p{InLatin}, такой же, как \p{Latin}и чудовищно нарушен.

  39. Код, который считает, что \p{InLatin}это почти всегда полезно, почти наверняка неверен.

  40. Кодекс, который полагает, что дан $FIRST_LETTERкак первая буква в некотором алфавите и $LAST_LETTERкак последняя буква в том же самом алфавите, это [${FIRST_LETTER}-${LAST_LETTER}]имеет какое-либо значение, почти всегда полностью сломанное и неправильное и бессмысленное.

  41. Код, который считает, что чье-то имя может содержать только определенные символы, является глупым, оскорбительным и неправильным.

  42. Код, который пытается преобразовать Unicode в ASCII, не просто ошибочен, его исполнителю никогда не разрешат снова работать в программировании. Период. Я даже не уверен, что их даже нужно снова увидеть, поскольку это, очевидно, пока не принесло им много пользы.

  43. Код, который считает, что есть какой-то способ притвориться, что кодировки текстовых файлов не существуют, сломан и опасен. С таким же успехом можно высунуть и другой глаз.

  44. Код, который преобразует неизвестные символы в ?неработающий, глупый, бессмысленный, и работает вопреки стандартной рекомендации, которая гласит: НЕ ДЕЛАТЬ! RTFM почему нет.

  45. Код, который полагает, что он может надежно угадать кодировку немаркированного текстового файла, виновен в роковом смешении высокомерия и наивности, который исправит только молния Зевса.

  46. Код, который считает, что вы можете использовать printfширину 🐪 для дополнения и обоснования данных Юникода, неверен и неверен.

  47. Код, который полагает, что как только вы успешно создадите файл с заданным именем, при запуске lsили readdirв окружающем каталоге вы обнаружите, что файл с именем, под которым вы его создали, содержит ошибки, сломан и ошибочен. Хватит удивляться этому!

  48. Код, который считает UTF-16 кодированием с фиксированной шириной, глуп, сломан и ошибочен. Отзыв их лицензии на программирование.

  49. Код, который обрабатывает кодовые точки из одной плоскости, отличной от кода из любой другой плоскости, фактически является ошибочным и неверным. Идти обратно в школу.

  50. Код, который считает, что подобные вещи /s/iмогут только совпадать, "S"либо "s"ошибаться, либо ошибаться. Вы были бы удивлены.

  51. Код, который используется \PM\pM*для поиска кластеров графемы вместо использования \X, поврежден и ошибочен.

  52. Людей, которые хотят вернуться в мир ASCII, следует искренне поощрять к этому, и в честь их славного обновления им должна быть предоставлена бесплатная электрическая ручная пишущая машинка для всех их потребностей при вводе данных. Сообщения, отправленные им, следует отправлять по телеграфу по 40 символов в строке и доставлять вручную курьером. СТОП.


😱 𝕾 𝖀 𝕸 𝕸 𝕬 𝕽 𝖄 😱


Я не знаю, сколько вы можете получить «Unicode по умолчанию в 🐪», чем то, что я написал. Ну, да, я делаю: вы должны использовать Unicode::Collateи Unicode::LineBreakтоже. И, вероятно, больше.

Как вы видите, есть слишком много Unicode вещей , которые вы действительно действительно должны беспокоиться о для там когда - либо существует такая вещь , как « по умолчанию в Unicode».

То, что вы собираетесь обнаружить, так же, как мы делали это в п. 5.8, что просто невозможно навязать все эти вещи к коду, который не был разработан с самого начала, чтобы объяснить их. Твой благонамеренный эгоизм просто сломал весь мир.

И даже после того, как вы это сделаете, по-прежнему есть критические проблемы, которые требуют большого количества размышлений, чтобы получить право. Там нет переключателя вы можете щелкнуть. Ничего, кроме мозга, а я имею в виду настоящий мозг , здесь не хватит. Есть чертовски много вещей, которые вы должны изучить. По модулю отступления к ручной пишущей машинке вы просто не можете надеяться пробраться в неведении. Это 21 век, и вы не можете желать Unicode умышленным невежеством.

Вы должны изучить это. Период. Никогда не будет так легко, что «все просто работает», потому что это гарантирует, что многие вещи не работают - что лишает законной силы предположение, что когда-либо может быть способ «заставить все это работать».

Возможно, вам удастся получить несколько разумных значений по умолчанию для очень немногих и очень ограниченных операций, но не думая о вещах намного больше, чем я думаю, у вас есть.

Как только один пример, каноническое упорядочение вызовет некоторые реальные головные боли. 😭 "\x{F5}" «õ» , "o\x{303}" «õ» , "o\x{303}\x{304}" «ȭ» и "o\x{304}\x{303}" «ō̃» должны совпадать с «õ» , но как в мире вы это сделаете? Это сложнее, чем кажется, но это то, что вам нужно учитывать. 💣

Если есть что-то, что я знаю о Perl, это то, что его биты Unicode делают и не делают, и вот что я вам обещаю: «̲ᴛ̲ʜ̲ᴇ̲ʀ̲ᴇ̲ ̲ɪ̲s̲ ̲ɴ̲ᴏ̲ ̲U̲ɴ̲ɪ̲ᴄ̲ᴏ̲ᴅ̲ᴇ̲ ̲ᴍ̲ᴀ̲ɢ̲ɪ̲ᴄ̲ ̲ʙ̲ᴜ̲ʟ̲ʟ̲ᴇ̲ᴛ̲ ̲» 😞

Вы не можете просто изменить некоторые значения по умолчанию и получить плавный ход. Это правда, что я запускаю 🐪 с PERL_UNICODEустановленным на "SA", но это все, и даже это в основном для командной строки. Для реальной работы я прошёл все многочисленные шаги, описанные выше, и делаю это очень, ** очень ** осторожно.


😈 ¡ƨdləɥ ƨᴉɥʇ ədoɥ puɐ ʻλɐp əɔᴉu ɐ əʌɐɥ ʻʞɔnl poo⅁ 😈

tchrist
источник
56
Как указал Шерм Пендли: «Все!». Если я сегодня напишу что-то новое, UTF-8 должен стать самым простым способом добиться цели. Не то. Ваш шаблон доказывает это. Не у всех есть такие знания, чтобы повернуть так много тумблеров в правильное положение. Извините, у меня был длинный и тяжелый день, поэтому я прокомментирую в основной записи завтра больше с примерами.
WK
17
Из приведенного выше списка следует сделать один вывод: не сворачивайте регистр. Просто не надо. Когда-либо. Вычислительно дорогой и с семантикой, которая в решающей степени зависит от того, что именно «локаль» пытается безуспешно идентифицировать.
Тим Брей
72
Неужели я единственный, кто находит ироничным то, что этот пост tchrist настолько дико отличается от FF / Chrome / IE / Opera, когда-нибудь до такой степени неразборчивости?
ущербный парень
15
В то время как я вообще люблю почту, и сделал upvote, одна вещь черт возьми меня. Существует много «кода, который ... сломан». Хотя я не спорю с утверждением, я думаю, что было бы хорошо показать разбитость. Таким образом это перешло бы (эта часть ответа) от разглагольствования к образованию.
36
@xenoterracide Нет, я не использовал намеренно проблемные кодовые точки; это сюжет, чтобы заставить вас установить супер-потрясающий шрифт Symbola Джорджа Дуроса , который охватывает Unicode 6.0. 😈 @depesz Здесь нет места, чтобы объяснить, почему каждое ошибочное предположение неправильно. @leonbloy Многое и многое из этого относится к Unicode в целом, а не только к Perl. Некоторые из этих материалов могут появиться в «Программировании на Perl», 4-е издание , выход которого запланирован на октябрь. 🎃 У меня есть один месяц, чтобы работать над ним, и Unicode ᴍᴇɢᴀ там; регулярные выражения тоже
tchrist
96

Есть две стадии обработки текста Unicode. Первый - «как я могу его ввести и вывести без потери информации». Второе - «как мне относиться к тексту в соответствии с местными языковыми соглашениями».

пост tchrist охватывает оба, но вторая часть - то, откуда 99% текста в его посте взято. Большинство программ даже не обрабатывают ввод / вывод правильно, поэтому важно понять это, прежде чем вы начнете беспокоиться о нормализации и сопоставлении.

Этот пост призван решить эту первую проблему

Когда вы читаете данные в Perl, не важно, какая это кодировка. Он выделяет некоторую память и хранит байты там. Если вы говоритеprint $str , он просто сбрасывает эти байты на ваш терминал, который, вероятно, настроен на то, чтобы предполагать, что все, что записано в него, является UTF-8, и ваш текст отображается.

Изумительный.

За исключением того, что это не так. Если вы попытаетесь обработать данные как текст, вы увидите, что происходит что-то плохое. Вам не нужно идти дальше, lengthчтобы увидеть, что Perl думает о вашей строке и что вы думаете о вашей строке не согласны. Напишите одну строчку, как: perl -E 'while(<>){ chomp; say length }'и введите, 文字化けи вы получите 12 ... не правильный ответ, 4.

Это потому, что Perl предполагает, что ваша строка не является текстом. Вы должны сказать ему, что это текст, прежде чем он даст вам правильный ответ.

Это достаточно просто; модуль Encode имеет функции для этого. Общей точкой входа является Encode::decode(или use Encode qw(decode), конечно). Эта функция берет некоторую строку из внешнего мира (то, что мы будем называть «октетами», причудливый способ сказать «8-битные байты») и превращает ее в некоторый текст, который Perl поймет. Первый аргумент - это имя кодировки символов, например «UTF-8» или «ASCII» или «EUC-JP». Второй аргумент - это строка. Возвращаемым значением является скаляр Perl, содержащий текст.

(Существует также Encode::decode_utf8, который предполагает UTF-8 для кодирования.)

Если мы перепишем наш однострочник:

perl -MEncode=decode -E 'while(<>){ chomp; say length decode("UTF-8", $_) }'

Мы набираем 文字 化 け и получаем «4» в результате. Успех.

Это, прямо сейчас, решение 99% проблем Unicode в Perl.

Ключ в том, что всякий раз, когда какой-либо текст попадает в вашу программу, вы должны его декодировать. Интернет не может передавать символы. Файлы не могут хранить символы. В вашей базе данных нет символов. Есть только октеты, и вы не можете рассматривать октеты как символы в Perl. Вы должны декодировать закодированные октеты в символы Perl с помощью модуля Encode.

Другая половина проблемы - получение данных из вашей программы. Это легко; ты просто говоришьuse Encode qw(encode) , решите, в какой кодировке будут находиться ваши данные (UTF-8 для терминалов, которые понимают UTF-8, UTF-16 для файлов в Windows и т. д.), и затем выводите результат encode($encoding, $data)вместо простого вывода $data.

Эта операция преобразует символы Perl, над которыми работает ваша программа, в октеты, которые могут использоваться внешним миром. Было бы намного проще, если бы мы могли просто посылать символы через Интернет или на наши терминалы, но мы не можем: только октеты. Поэтому мы должны конвертировать символы в октеты, иначе результаты не определены.

Подводя итог: закодировать все выходы и декодировать все входы.

Теперь поговорим о трех вопросах, которые делают это немного сложным. Первое - это библиотеки. Правильно ли они обрабатывают текст? Ответ ... они пытаются. Если вы загрузите веб-страницу, LWP вернет вам ваш результат в виде текста. Если вы вызываете правильный метод для результата, то есть (и это случается decoded_content, неcontent , что является просто потоком октетов, который он получил от сервера.) Драйверы базы данных могут быть ненадежными; если вы используете DBD :: SQLite только с Perl, это сработает, но если какой-то другой инструмент поместит текст, хранящийся в вашей базе данных в кодировке, отличной от UTF-8 ... ну ... это не будет правильно обрабатываться пока вы не напишите код для правильной обработки.

Вывод данных обычно проще, но если вы видите «широкие символы в печати», то вы знаете, что где-то испортили кодировку. Это предупреждение означает «эй, вы пытаетесь просочиться Perl-символы во внешний мир, и это не имеет никакого смысла». Кажется, что ваша программа работает (потому что другой конец обычно корректно обрабатывает необработанные символы Perl), но она сильно повреждена и может перестать работать в любой момент. Исправьте это с явным Encode::encode!

Вторая проблема - код в кодировке UTF-8. Если вы не скажете use utf8вверху каждого файла, Perl не будет считать, что ваш исходный код - UTF-8. Это означает, что каждый раз, когда вы говорите что-то вроде этого my $var = 'ほげ', вы впрыскиваете в свою программу мусор, который полностью разрушит все. Вам не нужно «использовать utf8», но если вы этого не сделаете, вы не должны использовать любые символы, не входящие в ASCII, в вашей программе.

Третья проблема заключается в том, как Perl обрабатывает прошлое. Давным-давно не было такого понятия, как Unicode, и Perl предполагал, что все было текстовым или двоичным кодом Latin-1. Поэтому, когда данные поступают в вашу программу и вы начинаете обрабатывать их как текст, Perl обрабатывает каждый октет как символ Latin-1. Вот почему, когда мы спросили длину «文字 化 け», мы получили 12. Perl предположил, что мы работаем со строкой Latin-1 «åååã» (которая состоит из 12 символов, некоторые из которых не печатаются).

Это называется «неявным обновлением», и это вполне разумно, но это не то, что вам нужно, если ваш текст не Latin-1. Вот почему так важно явно декодировать ввод: если вы этого не сделаете, Perl сделает это, и он может сделать это неправильно.

Люди сталкиваются с проблемами, когда половина их данных является правильной символьной строкой, а некоторые все еще двоичными. Perl интерпретирует двоичную часть, как будто это текст Latin-1, а затем объединяет ее с правильными символьными данными. Это будет выглядеть так, как будто правильное обращение с вашими персонажами нарушило вашу программу, но в действительности вы просто недостаточно исправили это.

Вот пример: у вас есть программа, которая читает текстовый файл в кодировке UTF-8, вы добавляете Unicode PILE OF POOк каждой строке и распечатываете ее. Вы пишете это так:

while(<>){
    chomp;
    say "$_ 💩";
}

А затем запустите некоторые данные в кодировке UTF-8, например:

perl poo.pl input-data.txt

Он печатает данные UTF-8 с poo в конце каждой строки. Отлично, моя программа работает!

Но нет, вы просто делаете двоичную конкатенацию. Вы читаете октеты из файла, удаляя\n помощью chomp, а затем добавляете байты в UTF-8 представлениеPILE OF POO символа. Когда вы пересмотрите свою программу, чтобы декодировать данные из файла и закодировать вывод, вы заметите, что вместо poo вы получаете мусор («ð ©»). Это заставит вас поверить, что декодирование входного файла - неправильная вещь. Это не.

Проблема в том, что poo неявно обновляется как latin-1. если тыuse utf8 сделаете буквальный текст вместо двоичного, то он снова заработает!

(Это проблема номер один, которую я вижу, когда помогаю людям с Юникодом. Они правильно расставались, и это нарушало их программу. Вот что печально в отношении неопределенных результатов: у вас может быть рабочая программа в течение длительного времени, но когда вы начинаете ее восстанавливать, это ломает. Не волнуйтесь, если вы добавляете операторы кодирования / декодирования в свою программу, и это ломается, это просто означает, что у вас есть больше работы. В следующий раз, когда вы с самого начала будете проектировать с Unicode, это будет намного легче!)

Это действительно все, что вам нужно знать о Perl и Unicode. Если вы скажете Perl, какие у вас данные, у вас будет лучшая поддержка Unicode среди всех популярных языков программирования. Однако, если вы предполагаете, что он будет волшебным образом знать, какой тип текста вы подаете, то вы безвозвратно уничтожите свои данные. То, что ваша программа работает сегодня на вашем терминале UTF-8, не означает, что она будет работать завтра с файлом в кодировке UTF-16. Так что сделайте это сейчас безопасным и избавьте себя от головной боли, связанной с уничтожением данных ваших пользователей!

Простая часть обработки Unicode - это кодирование вывода и декодирование ввода. Сложная часть - найти все ваши входные и выходные данные и определить, какая это кодировка. Но именно поэтому вы получаете большие деньги :)

jrockway
источник
Принцип хорошо объяснен, но практический подход к вводу / выводу отсутствует. Явное использование Encodeмодуля утомительно и подвержено ошибкам, и это делает чтение кода относительно ввода-вывода действительно болезненным. Уровни ввода / вывода обеспечивают решение, поскольку они прозрачно кодируют и декодируют, где это необходимо. openи учитывайте binmodeих спецификацию, а прагма openустанавливает значения по умолчанию, как рекомендует tchrist в своем ответе.
Палек,
48

Мы все согласны с тем, что это сложная проблема по многим причинам, но именно поэтому мы стараемся облегчить задачу для всех.

В CPAN недавно появился модуль utf8 :: all , который пытается «включить Unicode. Все это».

Как уже указывалось, вы не можете волшебным образом заставить всю систему (внешние программы, внешние веб-запросы и т. Д.) Также использовать Unicode, но мы можем работать вместе, чтобы сделать разумные инструменты, облегчающие решение общих проблем. Вот почему мы программисты.

Если utf8 :: all не делает то, что вы считаете нужным, давайте улучшим его, чтобы сделать его лучше. Или давайте создадим дополнительные инструменты, которые вместе могут максимально удовлетворить различные потребности людей.

`

Рэнди Стаунер
источник
5
Я вижу много возможностей для улучшения в цитируемом utf8::allмодуле. Это было написано перед unicode_stringsфункцией, которая Fɪɴᴀʟʟʏ ᴀɴᴅ ᴀᴛ Lᴏɴɢ Lᴀsᴛ исправляет регулярные выражения, чтобы иметь /uна них. Я не уверен, что это вызывает исключение при ошибках кодирования, и это то, что вы действительно должны иметь. Он не загружается в use charnames ":full"прагму, которая еще не загружена. Он не предупреждает о [a-z]и таких, printfструнных ширинах, используя \nвместо \Rи .вместо того , чтобы \X, но , возможно , those're больше Perl::Criticдела. Если бы это был я, я бы добавил 𝐍𝐅𝐃 в и 𝐍𝐅𝐂 из.
tchrist
13
@tchrist Система отслеживания проблем для utf8 :: все здесь. github.com/doherty/utf8-all/issues Они хотели бы услышать ваши предложения.
Шверн
4
@Schwern: Да, но не стесняйтесь воровать и ущипнуть от того, что я здесь написал. Если честно, я все еще чувствую / изучаю, что можно сделать против того, что должно быть сделано и где. Вот хороший пример от разгрузки сортировки: unichars -gs '/(?=\P{Ll})\p{Lower}|(?=\P{Lu})\p{Upper}/x' | ucsort --upper | cat -n | less -r. Точно так же маленькие шаги предварительной обработки, такие как, ... | ucsort --upper --preprocess='s/(\d+)/sprintf "%#012d", $1/ge'могут быть действительно хорошими, и я не хотел бы принимать решения других за них. Я все еще строю свой набор инструментов Unicode .
tchrist
35

Я думаю, вы неправильно понимаете Unicode и его отношение к Perl. Независимо от того, каким образом вы храните данные, Unicode, ISO-8859-1 и многие другие, ваша программа должна знать, как интерпретировать байты, которые она получает, как ввод (декодирование) и как представлять информацию, которую она хочет вывести (кодирование). ). Получите неверную интерпретацию, и вы искажаете данные. Внутри вашей программы нет какой-то волшебной настройки по умолчанию, которая бы рассказывала вещи вне вашей программы, как действовать.

Вы думаете, что это сложно, скорее всего, потому что вы привыкли ко всему быть ASCII. Все, о чем вы должны были думать, просто игнорировалось языком программирования и всеми вещами, с которыми он должен был взаимодействовать. Если бы все использовало только UTF-8, и у вас не было выбора, то UTF-8 был бы таким же простым. Но не все используют UTF-8. Например, вы не хотите, чтобы ваш дескриптор ввода думал, что он получает октеты UTF-8, если это не так, и вы не хотите, чтобы ваши дескрипторы вывода были UTF-8, если считывающая их вещь может обрабатывать UTF-8 , У Perl нет возможности узнать эти вещи. Вот почему вы программист.

Я не думаю, что Unicode в Perl 5 слишком сложен. Я думаю, что это страшно, и люди избегают этого. Есть разница Для этого я включил Unicode в Learning Perl, 6th Edition , и в Effective Perl Programming есть много вещей, связанных с Unicode . Вы должны потратить время, чтобы изучить и понять Unicode и как он работает. В противном случае вы не сможете использовать его эффективно.

Брайан Д. Фой
источник
3
Я думаю, у вас есть точка зрения: это страшно. Должно ли это быть? Для меня это Юникод, а использовать его в Perl5 нет (я не предполагаю, что ASCII - мой родной язык, по крайней мере, iso8859-4). Я установил Rakudo, и все, что я попробовал с UTF-8 (в этой ограниченной песочнице), работало из коробки. Я что-то пропустил? Я еще раз подчеркиваю: хорошо иметь хорошо настроенную поддержку Unicode, но в большинстве случаев в этом нет необходимости. Чтобы избавиться от страха по теме, один из способов состоит в том, что все много читают, чтобы понять внутреннее. Другое: у нас особая прагма, поэтому use utf8_everywhereлюди счастливы. Почему не последний?
WK
3
Я все еще думаю, что вы упускаете суть. Что сработало? Вам не нужно понимать внутренности. Вы должны понимать внешние аспекты и то, как вы хотите обрабатывать строки, которые имеют разные кодировки и разные представления одних и тех же символов. Прочитайте совет Тома снова. Бьюсь об заклад, большую часть того, что он говорит, вы обнаружите, что Ракудо не справляется с вами.
Брайан Д. Фой
1
@wk: Прочтите ответ Рэнди еще раз. Он уже сказал вам, каковы ограничения.
Брайан Д Фой
2
@ Брайан Д Фой: я думаю, что эти ограничения хороши, как говорит Трист, нет волшебной палочки для каждого аспекта (я признаю: я не видел большинство из них, прежде чем задавать этот вопрос здесь). Итак, когда мы покрываем множество базовых вещей чем-то вроде utf8 :: all, нет необходимости для всех создавать свой собственный огромный шаблон только для того, чтобы получить основы работы с utf8. Я имею в виду «совсем не бояться»: каждый может начать свои проекты, зная, что основы покрыты. Да, вы правы, проблем все еще много. Но когда начать легче, у нас будет больше людей, вовлеченных в решение этих проблем. ИМХО
WK
1
@wk - единственное «не так» с «utf8: all» или «uni :: perl» - это только один - они не находятся в CORE - поэтому каждый должен установить его из CPAN. И если вы считаете, что это не большой Разберитесь - переосмыслите, пожалуйста - да, проще использовать utf8 с вспомогательным модулем. Без него в Perl CORE по-прежнему есть поддержка юникода - но очень-очень сложно. И это неправильно.
jm666
28

Читая эту ветку, у меня часто складывается впечатление, что люди используют « UTF-8 » как синоним « Unicode ». Пожалуйста, сделайте различие между «кодовыми точками» Unicode, которые являются увеличенным родственником кода ASCII, и различными «кодировками» Unicode. И есть несколько из них, из которых UTF-8, UTF-16 и UTF-32 являются текущими, и еще несколько устарели.

Пожалуйста, UTF-8 (как и все другие кодировки ) существует и имеет значение только для ввода или вывода. Внутренне, начиная с Perl 5.8.1, все строки хранятся как Unicode "Code-points". Правда, вы должны включить некоторые функции, которые были описаны выше.

MeirG
источник
19
Я согласен, что люди слишком часто путают Uɴɪᴄᴏᴅᴇ с UTF-8⧸16⧸32, но в корне и критически неверно, что Uɴɪᴄᴏᴅᴇ - это просто какой-то расширенный набор символов относительно ᴀsᴄɪɪ. В лучшем случае это не что иное, как «ɪsᴏ ‑ 10646» . Uɴɪᴄᴏᴅᴇ включает в себя гораздо больше : правила для сопоставления, сворачивания падежа, формы нормализации, кластеры графем, переносы слов и строк, сценарии, числовые эквиваленты, ширины, двунаправленность, варианты глифов, контекстное поведение, локали, регулярные выражения, объединение классов, сотни свойств, & намного больше‼
tchrist
15
@tchrist: первым шагом является получение данных в вашу программу и из внешнего мира, не разрушая их. тогда вы можете беспокоиться о сортировке, складывании кейсов, вариантах глифов и т. д., детские шаги.
Jrockway
7
Я согласен, получение perl не для мусора ввода или вывода должно быть первым приоритетом. Я хотел бы иметь модуль или прагму, которые могли бы воплощать в себе следующую вымышленную беседу: «- Уважаемый Perl. Для этой программы все входные и выходные данные будут исключительно в формате UTF-8. Не могли бы вы не испортить мои данные? - Так вы говорите только о UFT-8. Вы уверены? - Да. - Действительно, действительно уверены? - Абсолютно. - И вы принимаете, что я могу вести себя странно, если мне подают данные не в формате UTF-8? - Да, хорошо. - Хорошо, тогда."
Хловдал
10

В дикой природе существует поистине ужасающее количество древнего кода, большая часть которого представлена ​​в виде обычных модулей CPAN. Я обнаружил, что должен быть довольно осторожным при включении Unicode, если использую внешние модули, на которые он может повлиять, и все еще пытаюсь выявить и исправить некоторые ошибки Unicode в нескольких Perl-скриптах, которые я регулярно использую (в частности, происходит сбой iTiVo) плохо на всем, что не является 7-битным ASCII из-за проблем с транскодированием).

geekosaur
источник
Я имел в виду использование -Cопции, чтобы убедиться, что Perl находится на той же странице, что и я в Юникоде, потому что я продолжаю предлагать использовать ISO 8859/1 вместо Юникода, даже если я явно настроен $LANGи $LC_ALLправильно настроен . (Это может на самом деле отражать ошибки в библиотеках языковых стандартов платформы.) Как бы то ни было, очень досадно, что я не могу использовать iTivo в программах с акцентами в них, потому что скрипты Perl, которые выполняют работу, сбиваются с ошибками преобразования.
geekosaur
3
Одинокий -Cбез вариантов глючит и подвержен ошибкам . Ты разбиваешь мир. Установите PERL5OPTenvariable, -Cи вы поймете, что я имею в виду. Мы попробовали этот путь назад в v8.8, и это было катастрофой. Вы просто не можете и не должны сообщать программам, которые этого не ожидают, о том, что теперь они имеют дело с Unicode, нравится им это или нет. Есть также проблемы с безопасностью. По крайней мере, все, что делает print while <>, сломается, если передаются двоичные данные. Так же будет весь код базы данных. Это ужасная идея.
tchrist
1
Я говорил в общем, на самом деле, а не конкретно -Cбез вариантов. Конкретный вызов, с которым я работал, был -CSDA. Тем не менее, я застрял с 5.8.x в течение долгого времени (привет MacPorts ...), так что, возможно, это было частью этого.
geekosaur
1
Я бегу с PERL_UNICODE, установленным в SA. Вы НЕ МОЖЕТЕ установить его на D.
tchrist
@tchrist: некоторые варминты Perl публикуют код, показывающий использование -CSDA и PERL_UNICODE = SDA . Пожалуйста, используйте свое влияние в сообществе. Он должен быть остановлен!
Эшли
1

Вы должны включить функцию Unicode Strings, и это по умолчанию, если вы используете v5.14;

Вы не должны использовать Unicode-идентификаторы esp. для внешнего кода через utf8, поскольку они небезопасны в perl5, только cperl понял это правильно. Смотрите, например, http://perl11.org/blog/unicode-identifiers.html

Относительно utf8 для ваших файловых дескрипторов / потоков: вам нужно самостоятельно решить кодировку ваших внешних данных. Библиотека не может этого знать, и поскольку даже libc не поддерживает utf8, правильные данные utf8 встречаются редко. Там больше wtf8, аберрация окон utf8 вокруг.

Кстати: Moose на самом деле не "Modern Perl", они просто похитили имя. Moose идеально подходит для постмодернистского Perl в стиле Ларри Уолла, смешанного с стилем Бьярна Страуструпа, с эклектичной аберрацией правильного синтаксиса perl6, например, использованием строк для имен переменных, синтаксиса ужасных полей и очень незрелой наивной реализацией, которая в 10 раз медленнее, чем правильная реализация. cperl и perl6 - настоящие современные perls, где форма следует за функцией, а реализация сокращена и оптимизирована.

rurban
источник