Без use utf8
Perl інтерпретує ваш рядок як послідовність однобайтових символів. Як видно з цього, у вашому рядку є чотири байти:
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
Перші три байти складають вашого персонажа, останній - це подача рядків.
Заклик до print
надсилає ці чотири символи до STDOUT. Потім ваша консоль розробляє, як відображати ці символи. Якщо для вашої консолі встановлено використання UTF8, вона буде інтерпретувати ці три байти як ваш єдиний символ, і саме це відображається.
Якщо додати в utf8
модуль, все інакше. У цьому випадку Perl інтерпретує ваш рядок як лише два символи.
$ perl -Mutf8 -E 'say join ":", map { ord } split //, "鸡\n";'
40481:10
За замовчуванням рівень вводу-виводу Perl передбачає, що він працює з однобайтовими символами. Отже, коли ви намагаєтесь надрукувати багатобайтовий символ, Perl думає, що щось не так, і видає вам попередження. Як завжди, ви можете отримати більше пояснень щодо цієї помилки, включивши use diagnostics
. Це скаже так:
(S utf8) Perl зустрів широкого персонажа (> 255), коли не очікував такого. Це попередження за замовчуванням увімкнено для вводу-виводу (наприклад, друк). Найпростіший спосіб заспокоїти це попередження - просто додати до виводу рівень: utf8, наприклад binmode STDOUT, ': utf8'. Інший спосіб вимкнути попередження - не додавати жодних попереджень 'utf8'; але це часто наближається до обману. Загалом, ви повинні явно позначити файл-маніпулятор кодуванням, див. Open та perlfunc / binmode.
Як зазначали інші, вам потрібно сказати Perl прийняти багатобайтовий вихід. Існує багато способів зробити це (див. Підручник з Perl Unicode для деяких прикладів). Одним з найпростіших способів є використання -CS
прапора командного рядка, який повідомляє трьом стандартним маніпуляторам файлів (STDIN, STDOUT та STDERR) справу з UTF8.
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
проти
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Юнікод - це велика і складна область. Як ви вже бачили, багато простих програм, здається, роблять правильно, але з помилкових причин. Коли ви починаєте виправляти частину програми, речі часто погіршуються, поки ви не виправите всю програму.