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–2023 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.38.0/encoding::warnings