Без use utf8Perl интерпретирует вашу строку как последовательность однобайтовых символов. Как видно из этого, в вашей строке четыре байта:
$ perl -E 'say join ":", map { ord } split //, "鸡\n";'
233:184:161:10
Первые три байта составляют ваш символ, последний - перевод строки.
Вызов to 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 Tutorial ). Один из самых простых способов - использовать -CSфлаг командной строки, который сообщает трем стандартным дескрипторам файлов (STDIN, STDOUT и STDERR) работать с UTF8.
$ perl -Mutf8 -e 'print "鸡\n";'
Wide character in print at -e line 1.
鸡
против
$ perl -Mutf8 -CS -e 'print "鸡\n";'
鸡
Юникод - это большая и сложная область. Как вы видели, кажется, что многие простые программы поступают правильно, но по неправильным причинам. Когда вы начинаете исправлять часть программы, все становится еще хуже, пока вы не исправите всю программу.