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.30.3/encoding::warnings