encoding::warnings
СОДЕРЖАНИЕ
ИМЯ
encoding::warnings - Предупреждение при неявных преобразованиях кодировок
ВЕРСИЯ
В данном документе описана версия 0.13 модуля encoding::warnings, выпущенная 20 июня 2016 года.
ПРИМЕЧАНИЕ
Начиная с Perl 5.26.0, этот модуль не оказывает никакого эффекта. Внутренняя функция Perl, которая использовалась для реализации этого модуля, была удалена. В последние годы в ядре Perl проведена большая работа по устранению несоответствий в обработке обновленных и пониженных строк. Кроме того, pragma encoding, вызывавший многие из этих проблем, больше не поддерживается. Таким образом, предупреждения, которые генерировал этот модуль, больше не нужны.
Поэтому, если вы загрузите этот модуль в Perl 5.26.0, вы получите одно предупреждение о том, что модуль больше не поддерживается; и после этого модуль ничего не будет делать.
СИНОПСИС
use encoding::warnings; # or 'FATAL' to raise fatal exceptions
utf8::encode($a = chr(20000)); # a byte-string (raw bytes)
$b = chr(20000); # a unicode-string (wide characters)
# "Bytes implicitly upgraded into wide characters as iso-8859-1"
$c = $a . $b; ОПИСАНИЕ
Обзор проблемы
По умолчанию в модели Unicode Perl существует фундаментальное несоответствие: неявное повышение приоритета байтовых строк до строк Unicode предполагает, что они были закодированы в ISO 8859-1 (Latin-1), но строки Unicode понижаются с кодировкой UTF-8. Это происходит потому, что первые 256 кодовых точек в Unicode совпадают с Latin-1.
Однако это неявное повышение приоритета может легко привести к проблемам, если вы смешиваете строки Unicode с данными, не относящимися к Latin-1 — например, байтовыми строками, закодированными в UTF-8 или других кодировках. Ошибка проявится только при записи объединенной строки в выходной поток, в этот момент будет невозможно определить, где произошло неявное повышение приоритета.
Обнаружение проблемы
Этот модуль упрощает процесс диагностики таких проблем. Просто поместите эту строку в начало вашей основной программы:
use encoding::warnings; После этого неявное повышение приоритета байтов с высоким битом будет выводить предупреждение. Пример: Bytes implicitly upgraded into wide characters as iso-8859-1 at - line 7.
Однако строки, состоящие только из кодовых точек ASCII (0x00..0x7F) не будут вызывать это предупреждение.
Вы также можете сделать предупреждения фатальными, импортировав этот модуль следующим образом:
use encoding::warnings 'FATAL'; Решение проблемы
В большинстве случаев это предупреждение возникает при конкатенации байтовой строки со строкой Unicode. Существует несколько способов его решения:
-
Повышение приоритета обеих сторон до строк Unicode
Если вашей программе не требуется совместимость с Perl 5.6 и более ранними версиями, рекомендуемый подход заключается в применении соответствующих дисциплин ввода-вывода, чтобы все данные в вашей программе стали строками Unicode. См. encoding, open и "binmode" в perlfunc для получения информации.
-
Понижение приоритета обеих сторон до байтовых строк
Этот метод также работает, особенно если вы уверены, что все ваши данные находятся в одной кодировке или если необходима совместимость со старыми версиями Perl.
Вы можете понизить приоритет строк с помощью
Encode::encodeиutf8::encode. См. Encode и utf8 для получения подробностей. -
Указание кодировки для неявного повышения приоритета байтовых строк
Если вы уверены, что все байтовые строки будут в определенной кодировке, например, UTF-8, и вам не нужно поддерживать старые версии Perl, используйте pragma
encoding:use encoding 'utf8';Аналогично, это позволит заглушить предупреждения от этого модуля и сохранить поведение по умолчанию:
use encoding 'iso-8859-1';Однако обратите внимание, что
use encodingна самом деле имело три отдельных эффекта:-
Слой PerlIO для STDIN и STDOUT
Это аналогично тому, что делает pragma open.
-
Литеральные преобразования
Это преобразует все литеральные строки в вашей программе в строки Unicode (эквивалентно
use utf8), декодируя их с помощью указанной кодировки. -
Неявное повышение приоритета для байтовых строк
Это заглушит предупреждения от этого модуля, как показано выше.
Поскольку литеральные преобразования также работают с пустыми строками, это может удивить некоторых людей:
use encoding 'big5'; my $byte_string = pack("C*", 0xA4, 0x40); print length $a; # 2 here. $a .= ""; # concatenating with a unicode string... print length $a; # 1 here!Другими словами, не делайте
use encoding, если вы не уверены, что программа не будет работать с сырыми 8-битными бинарными данными.Однако вариант
Filter => 1use encodingне повлияет на неявное повышение приоритета для байтовых строк и, таким образом, не сможет заглушить предупреждения от этого модуля. См. encoding для получения дополнительной информации. -
ОГРАНИЧЕНИЯ
Для Perl 5.9.4 или более поздних версий эффект этого модуля является лексическим.
Для версий Perl до 5.9.4 этот модуль влияет на весь скрипт, а не только на его лексический блок.
СМОТРИТЕ ТАКЖЕ
АВТОРЫ
Audrey Tang
АВТОРСКИЕ ПРАВА
Авторские права 2004, 2005, 2006, 2007 Audrey Tang <cpan@audreyt.org>.
Эта программа является свободной программной; вы можете перераспределять её и/или изменять её на тех же условиях, что и Perl сам по себе.
См. http://www.perl.com/perl/misc/Artistic.html
© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.28.3/encoding::warnings