内容

名称

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”相同的编码的别名。

对于在终端窗口(在某些系统上称为“控制台”)中运行的程序,"locale" 编码通常是输入和输出的最佳选择。一些系统允许我们查询终端的编码集,Encode::Locale 会在可用时执行此操作,并将这些编码在 Encode 别名 "console_in" 和 "console_out" 下公开。对于无法确定终端编码的系统,它们将被别名为与 "locale" 相同的编码。建议使用 "console_in" 用于已知来自终端的输入,使用 "console_out" 用于输出到终端。

除了安排各种 Encode 别名之外,还提供了以下函数和变量:

decode_argv( )
decode_argv( Encode::FB_CROAK )

这将对 Perl 的命令行参数(@ARGV 数组)进行就地解码。

默认情况下,该函数将用 "\x{FFFD}"(Unicode 替换字符)替换无法解码的字符。

提供的任何参数都将作为 CHECK 传递给底层的 Encode::decode() 调用。传递值 Encode::FB_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 替换字符)替换无法解码的字符。

没有接口可以请求与 decode_argv() 相同的替代 CHECK 行为。如果需要,您需要自己调用 encode/decode。例如

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 模块识别,则此函数将抛出异常。

使用参数强制 $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 基本上有两套 API。一个宽 API(基于传递 UTF-16 字符串)和一个基于字节的 API,基于一个名为 ANSI 的字符集。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 <[email protected]>。

本库是自由软件;您可以在 Perl 本身相同的条款下重新发布和/或修改它。