use utf8
только намекает интерпретатору/компилятору Perl, что ваш файл закодирован в UTF-8. Если у вас есть строки с установленным старшим битом, он автоматически закодирует их в Unicode.
Если у вас есть переменная, закодированная в iso-8859-1, вы должны ее декодировать. Тогда ваша переменная находится во внутреннем формате юникода. Это utf8, но вам все равно, какую кодировку Perl использует внутри.
Теперь, если вы хотите напечатать такую строку, вам нужно преобразовать строку Unicode обратно в строку байтов. Вам нужно сделать encode
в этой строке. Если вы не выполните кодировку вручную, perl
сама закодирует ее обратно в iso-8859-1. Это кодировка по умолчанию.
Прежде чем напечатать свою переменную $x, вам нужно сделать с ней $x = encode('UTF-8', $x)
.
Для правильной обработки UTF-8 вам всегда нужно decode() каждый внешний ввод через ввод-вывод. И вам всегда нужно encode() все, что покидает вашу программу.
Чтобы изменить кодировку ввода/вывода по умолчанию, вы можете использовать что-то вроде этого.
use utf8;
use open ':encoding(UTF-8)';
use open ':std';
Первая строка говорит, что ваш исходный код закодирован в utf8. Вторая строка говорит, что каждый ввод/вывод должен автоматически кодироваться в utf8. Важно отметить, что open()
также открывает файл в режиме utf8. Если вы работаете с двоичными файлами, вам нужно вызвать binmode()
для дескриптора.
Но вторая строка не меняет обработку STDIN, STDOUT или STDERR. Третья строка изменит это.
Вероятно, вы можете использовать модуль utf8:all, который упрощает этот процесс. Но всегда хорошо понимать, как все это работает за кулисами.
Чтобы исправить свой пример. Один из возможных способов таков:
#!/usr/bin/env perl
use Date::Holidays::DK;
use Encode;
use Devel::Peek;
my $x = decode("iso-8859-1",
is_dk_holiday(2011,1,1)
);
Dump($x);
print encode("UTF-8", "January 1st is '$x'\n");
person
David Raab
schedule
14.07.2011