encoding::warnings - 警告隱式編碼轉換
此文件說明 encoding::warnings 的版本 0.13,於 2016 年 6 月 20 日發布。
從 Perl 5.26.0 開始,此模組已無作用。用於實作此模組的 Perl 內部功能已移除。近年來,Perl 核心已投入大量工作,以消除升級字串與降級字串處理上的差異。此外,造成許多問題的 encoding pragma 已不再受支援。因此,此模組產生的警告已不再必要。
因此,如果您在 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 字串與非 Latin1 資料(即以 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 及更早版本相容,建議的方式是套用適當的 IO 規範,讓程式中的所有資料都變成 Unicode 字串。請參閱 編碼、開啟 和 perlfunc 中的「binmode」 以了解如何執行。
將兩邊都降級為位元組字串
另一種方式也行得通,特別是如果你確定所有資料都使用相同的編碼,或是需要與舊版 Perl 相容時。
你可以使用 Encode::encode
和 utf8::encode
將字串降級。請參閱 編碼 和 utf8 以取得詳細資料。
指定編碼以進行隱式位元組字串升級
如果你確信所有位元組字串都會使用特定的編碼,例如 UTF-8,而且不需要支援舊版 Perl,請使用 encoding
pragma
use encoding 'utf8';
同樣地,這將消除此模組發出的警告,並保留預設行為
use encoding 'iso-8859-1';
不過,請注意 use encoding
實際上具有三個不同的效果
STDIN 和 STDOUT 的 PerlIO 層
這類似於 開啟 pragma 的作用。
文字轉換
這會將程式中的所有文字字串轉換為 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
。
不過,use encoding
的 Filter => 1
風格不會影響位元組字串的隱式升級,因此無法消除此模組的警告。請參閱 encoding 以取得更多詳細資料。
對於 Perl 5.9.4 或更新版本,此模組的效果是詞彙的。
對於 5.9.4 之前的 Perl 版本,此模組會影響整個指令碼,而不是其詞彙區塊內部。
Audrey Tang
版權所有 2004、2005、2006、2007 Audrey Tang <cpan@audreyt.org>。
此程式是自由軟體;您可以在與 Perl 相同的條款下重新散布或修改它。