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–2021 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.34.0/encoding::warnings