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 => 1отuse 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.36.0/encoding::warnings