为什么 Encoding.default_external 不尊重 LANG?
Why doesn't Encoding.default_external respect LANG?
据我了解,Ruby的Encoding.default_external
是根据环境变量LC_ALL
和LANG
赋予的默认值,优先考虑前者。我已经 运行 发现了几个错误,即使环境变量设置为 UTF-8,默认的外部编码以某种方式最终设置为 ASCII。
例如:
$ irb
irb(main):001:0> Encoding.default_external
=> #<Encoding:US-ASCII>
irb(main):002:0> ENV['LC_ALL']
=> nil
irb(main):003:0> ENV['LANG']
=> "en_US.UTF-8"
在发生这种情况的环境中,我还搜索了所有正在加载的 gem,以寻找手动设置默认外部编码的任何代码,但没有找到任何东西。我在上面看到的怎么可能?我在上面使用 Ruby 2.2,但我已经看到所有 Ruby 2.x 版本都发生了这种情况。
我明白了。不仅需要设置 LANG
环境变量,而且必须为 OS 生成它所指定的语言环境。在股票 Linux 图像上,默认语言环境可能不是 UTF-8。在我的特定情况下,我使用的是 Debian 7.7,默认语言环境是 "POSIX"。我能够通过安装 locales 包并按照交互式提示生成 en_US.UTF-8 语言环境来设置默认语言环境:
$ apt-get -y install locales
如果已经安装了 locales 包,您可以重新配置它:
$ dpkg-reconfigure locales
现在设置 LANG
将更改当前系统区域设置,Ruby 的 Encoding.default_external
将正确设置:
$ export LANG=en_US.UTF-8
$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
$ irb
irb(main):001:0> Encoding.default_external
=> #<Encoding:UTF-8>
有关如何自动生成和配置默认区域设置而不是交互执行的示例,请查看 this Docker image。
据我了解,Ruby的Encoding.default_external
是根据环境变量LC_ALL
和LANG
赋予的默认值,优先考虑前者。我已经 运行 发现了几个错误,即使环境变量设置为 UTF-8,默认的外部编码以某种方式最终设置为 ASCII。
例如:
$ irb
irb(main):001:0> Encoding.default_external
=> #<Encoding:US-ASCII>
irb(main):002:0> ENV['LC_ALL']
=> nil
irb(main):003:0> ENV['LANG']
=> "en_US.UTF-8"
在发生这种情况的环境中,我还搜索了所有正在加载的 gem,以寻找手动设置默认外部编码的任何代码,但没有找到任何东西。我在上面看到的怎么可能?我在上面使用 Ruby 2.2,但我已经看到所有 Ruby 2.x 版本都发生了这种情况。
我明白了。不仅需要设置 LANG
环境变量,而且必须为 OS 生成它所指定的语言环境。在股票 Linux 图像上,默认语言环境可能不是 UTF-8。在我的特定情况下,我使用的是 Debian 7.7,默认语言环境是 "POSIX"。我能够通过安装 locales 包并按照交互式提示生成 en_US.UTF-8 语言环境来设置默认语言环境:
$ apt-get -y install locales
如果已经安装了 locales 包,您可以重新配置它:
$ dpkg-reconfigure locales
现在设置 LANG
将更改当前系统区域设置,Ruby 的 Encoding.default_external
将正确设置:
$ export LANG=en_US.UTF-8
$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
$ irb
irb(main):001:0> Encoding.default_external
=> #<Encoding:UTF-8>
有关如何自动生成和配置默认区域设置而不是交互执行的示例,请查看 this Docker image。