Я думаю, что столкнулся с проблемой с Unicode и IO::Handle. Очень вероятно, что я делаю что-то не так. Я хочу получать и удалять отдельные символы Юникода (не байты) из IO::Handle. Но я получаю удивительную ошибку.
#!/usr/local/bin/perl
use 5.016;
use utf8;
use strict;
use warnings;
binmode(STDIN, ':encoding(utf-8)');
binmode(STDOUT, ':encoding(utf-8)');
binmode(STDERR, ':encoding(utf-8)');
my $string = qq[a Å];
my $fh = IO::File->new();
$fh->open(\$string, '<:encoding(UTF-8)');
say $fh->getc(); # a
say $fh->getc(); # SPACE
say $fh->getc(); # Å LATIN CAPITAL LETTER A WITH RING ABOVE (U+00C5)
$fh->ungetc(ord("Å"));
say $fh->getc(); # should be A RING again.
Сообщение об ошибке из строки ungetc(): «Неверный формат символа UTF-8 (неожиданный конец строки), скажем, в строке 21 unicode.pl. «\x{00c5}
» не соответствует utf8 в строке 21 unicode.pl». Но это правильный гекс для персонажа, и он должен соответствовать персонажу.
Я использовал шестнадцатеричный редактор, чтобы убедиться, что байты для A-RING верны для UTF-8.
Кажется, это проблема для любого двухбайтового символа.
Последнее слово выводит '\xC5' (буквально четыре символа: обратная косая черта, x, C, 5).
И я проверил это, читая из файлов вместо скалярных переменных. Результат тот же.
Это Perl 5, версия 16, Subversion 2 (v5.16.2), созданный для darwin-2level.
И скрипт сохраняется в UTF-8. Это было первое, что я проверил.
binmode(STDIN, ':encoding(utf-8)'); binmode(STDOUT, ':encoding(utf-8)'); binmode(STDERR, ':encoding(utf-8)');
можно записать какuse open ':std', ':encoding(utf-8)';
. (Бонус, это происходит во время компиляции.) - person ikegami   schedule 06.01.2013my $fh = IO::File->new(); $fh->open(\$string, '<:encoding(UTF-8)');
можно записать какopen(my $fh, '<:encoding(UTF-8)', \$string)
. Да, вы все еще можете использовать методы. - person ikegami   schedule 06.01.2013