內容

名稱

ExtUtils::MakeMaker::Locale - 捆綁的 Encode::Locale

語法

use Encode::Locale;
use Encode;

$string = decode(locale => $bytes);
$bytes = encode(locale => $string);

if (-t) {
    binmode(STDIN, ":encoding(console_in)");
    binmode(STDOUT, ":encoding(console_out)");
    binmode(STDERR, ":encoding(console_out)");
}

# Processing file names passed in as arguments
my $uni_filename = decode(locale => $ARGV[0]);
open(my $fh, "<", encode(locale_fs => $uni_filename))
   || die "Can't open '$uni_filename': $!";
binmode($fh, ":encoding(locale)");
...

說明

在許多應用程式中,讓 Perl 使用 Unicode 來處理字串是很明智的。Perl 與外界的許多介面仍然是基於位元組的。因此,程式需要解碼從外部進入程式的位元組字串,並在輸出時再次編碼它們。

POSIX 地區設定系統用於指定使用者要求的語言慣例以及用於使用和輸出的首選字元集。Encode::Locale 模組會查詢字元集和編碼(在地區設定術語中稱為 CODESET),並安排 Encode 模組在名稱「locale」下知道此編碼。這表示可以透過呼叫 Encode::encode(locale => $bytes) 將從環境中取得的位元組轉換為 Unicode 字串,並透過 Encode::decode(locale => $string) 再次轉換回來。

當檔案系統介面將檔案名稱傳遞進出程式時,我們也需要小心。作業系統的趨勢是使用實際上不依賴於地區設定的固定檔案編碼;而此模組會決定最適合檔案名稱的編碼。Encode 模組會在名稱「locale_fs」下知道此編碼。對於傳統的 Unix 系統,這將是與「locale」相同編碼的別名。

對於在終端機視窗中執行的程式(在某些系統上稱為「主控台」),「區域設定」編碼通常是預期輸入和輸出的好選擇。某些系統允許我們查詢終端機的編碼設定,而 Encode::Locale 會在可用的情況下執行此動作,並讓這些編碼在 Encode 別名「console_in」和「console_out」下為人所知。對於我們無法判斷終端機編碼的系統,這些編碼將與「區域設定」相同的編碼別名。建議將「console_in」用於已知來自終端機的輸入,而將「console_out」用於輸出至終端機。

除了安排各種 Encode 別名之外,還提供了以下函式和變數

decode_argv( )
decode_argv( Encode::FB_CROAK )

這將就地解碼 Perl 的命令列引數(@ARGV 陣列)。

預設情況下,此函式會將無法解碼的字元替換為「\x{FFFD}」,即 Unicode 替換字元。

提供的任何引數都會傳遞為 CHECK 給底層的 Encode::decode() 呼叫。傳遞值 Encode::FB_CROAK 以便在無法解碼所有命令列引數時讓解碼 croak。有關 CHECK 其他選項的詳細資訊,請參閱 "Encode 中的「處理格式錯誤的資料」"

env( $uni_key )
env( $uni_key => $uni_value )

取得/設定環境變數的介面。傳回目前的 Unicode 字串值。$uni_key 和 $uni_value 引數也預期為 Unicode 字串。傳遞 undef 作為 $uni_value 會刪除名稱為 $uni_key 的環境變數。

傳回的值會將無法解碼的字元替換為「\x{FFFD}」,即 Unicode 替換字元。

沒有介面可以要求替代 CHECK 行為,如 decode_argv()。如果您需要,您需要自己呼叫編碼/解碼。例如

my $key = Encode::encode(locale => $uni_key, Encode::FB_CROAK);
my $uni_value = Encode::decode(locale => $ENV{$key}, Encode::FB_CROAK);
reinit( )
reinit( $encoding )

從區域設定重新初始化編碼。如果您變更了環境中任何可能影響區域設定的內容,您會想要呼叫此函式。

如果 Encode 模組無法辨識確定的編碼,此函式將會 croak。

使用引數強制 $ENCODING_... 變數設定為給定的值。

$ENCODING_LOCALE

已確定適合目前區域設定的編碼名稱。 Encode 將此編碼稱為「locale」。

$ENCODING_LOCALE_FS

已確定適合涉及檔案名稱的檔案系統介面的編碼名稱。 Encode 將此編碼稱為「locale_fs」。

$ENCODING_CONSOLE_IN
$ENCODING_CONSOLE_OUT

用於讀取和寫入主控台輸出的編碼。 Encode 將這些編碼稱為「console_in」和「console_out」。

備註

此表格摘要了由 Encode::Locale 模組設定的編碼對應。

Encode      |         |              |
Alias       | Windows | Mac OS X     | POSIX
------------+---------+--------------+------------
locale      | ANSI    | nl_langinfo  | nl_langinfo
locale_fs   | ANSI    | UTF-8        | nl_langinfo
console_in  | OEM     | nl_langinfo  | nl_langinfo
console_out | OEM     | nl_langinfo  | nl_langinfo

Windows

Windows 基本上有 2 組 API。一個是寬廣 API(基於傳遞 UTF-16 字串),另一個是基於稱為 ANSI 的字元集的位元組基礎 API。目前 Perl 與作業系統的常規介面只使用 ANSI API。很遺憾的是,ANSI 不是單一字元集。

對應於 ANSI 的編碼因 Windows 的不同版本而異。對於許多 Windows 的西方版本,ANSI 對應於 CP-1252,這是一個類似於 ISO-8859-1 的字元集。概念上,ANSI 字元集類似於 POSIX 區域設定 CODESET,因此此模組會找出 ANSI 編碼頁,並將其提供為 $ENCODING_LOCALE 和「locale」編碼別名。

Windows 系統也使用另一個位元組基礎字元集運作。它稱為 OEM 編碼頁。這是主控台作為輸入和輸出的編碼。OEM 編碼頁與 ANSI 編碼頁不同是很常見的。

Mac OS X

在 Mac OS X 上,檔案系統編碼始終為 UTF-8,而區域設定則可以像 POSIX 系統一樣設定為正常。

Mac OS X 上的檔案名稱會在作業系統層級轉換為 NFD 形式。使用 NFC 檔案名稱建立的檔案會以 NFD 形式從 readdir() 進入。有關 NFD/NFC 的詳細資訊,請參閱 Unicode::Normalize

事實上,Apple 沒有遵循 Unicode NFD 標準,因為並非所有字元範圍都已分解。聲稱這樣可以避免舊 Mac 文字編碼來回轉換的問題。請參閱 Encode::UTF8Mac 以取得詳細資訊。

POSIX (Linux 及其他 Unix)

檔案系統可能因檔案名稱要使用的編碼而有所不同。由於此模組無法實際找出正確的編碼,因此會採用最佳猜測,也就是假設檔案名稱是根據目前區域設定進行編碼。建議使用者總是將 UTF-8 指定為區域設定字元集。

另請參閱

I18N::LanginfoEncodeTerm::Encoding

作者

版權所有 2010 Gisle Aas <gisle@aas.no>。

此函式庫是自由軟體;您可以在與 Perl 相同的條款下重新散布或修改它。