encoding::warnings - 警告隐式编码转换
本文档描述了 2016 年 6 月 20 日发布的 encoding::warnings 版本 0.13。
从 Perl 5.26.0 开始,此模块不再起作用。用于实现此模块的内部 Perl 功能已被移除。近年来,Perl 核心做了很多工作来消除升级字符串和降级字符串处理之间的差异。此外,导致许多问题的 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;
默认情况下,Perl 的 unicode 模型存在一个基本的不对称性:从字节字符串到 unicode 字符串的隐式升级假设它们是用 ISO 8859-1 (Latin-1) 编码的,但 unicode 字符串是用 UTF-8 编码降级的。这是因为 Unicode 中的前 256 个码点恰好与 Latin-1 相同。
但是,如果您碰巧将 unicode 字符串与非 Latin-1 数据(即 UTF-8 或其他编码的字节字符串)混合使用,这种静默升级很容易导致问题。错误不会在组合字符串写入输出之前显现,到那时,就无法看到静默升级发生在哪里。
此模块简化了诊断此类问题的过程。只需将此行放在主程序的顶部
use encoding::warnings;
之后,高位字节的隐式升级将引发警告。例如:字节隐式升级为宽字符,编码为 iso-8859-1,位于 - 第 7 行
。
但是,仅由 ASCII 代码点(0x00
..0x7F
)组成的字符串不会触发此警告。
您也可以通过以下方式将警告设为致命错误
use encoding::warnings 'FATAL';
大多数情况下,此警告发生在字节字符串与 Unicode 字符串连接时。有几种方法可以解决它
将两边都升级为 Unicode 字符串
如果您的程序不需要与 Perl 5.6 及更早版本兼容,建议的方法是应用适当的 IO 规则,以便程序中的所有数据都成为 Unicode 字符串。有关如何操作,请参阅 编码、打开 和 "perlfunc 中的 binmode"。
将两边都降级为字节字符串
另一种方法也适用,尤其是在您确定所有数据都使用相同的编码,或者需要与旧版本的 Perl 兼容的情况下。
您可以使用 Encode::encode
和 utf8::encode
降级字符串。有关详细信息,请参阅 Encode 和 utf8。
为隐式字节字符串升级指定编码
如果您确信所有字节字符串都将使用特定编码(如 UTF-8),并且不需要支持旧版本的 Perl,请使用 encoding
编译指示
use encoding 'utf8';
同样,这将消除来自此模块的警告,并保留默认行为
use encoding 'iso-8859-1';
但是,请注意,use encoding
实际上有三个不同的效果
STDIN 和 STDOUT 的 PerlIO 层
这类似于 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!
换句话说,除非您确定程序不会处理任何原始的 8 位二进制数据,否则不要使用 use encoding
。
但是,Filter => 1
风格的 use encoding
不会影响字节字符串的隐式升级,因此无法消除来自此模块的警告。有关详细信息,请参阅 编码。
对于 Perl 5.9.4 或更高版本,此模块的效果是词法范围的。
对于 5.9.4 之前的 Perl 版本,此模块会影响整个脚本,而不是其词法块内部。
Audrey Tang
版权所有 2004, 2005, 2006, 2007 by Audrey Tang <[email protected]>。
本程序是自由软件;您可以根据与 Perl 本身相同的条款重新发布和/或修改它。