使用 Plack 和 Middlewares 时将默认 perl 的 IO 切换为 utf-8 是不是正确?
Posted
技术标签:
【中文标题】使用 Plack 和 Middlewares 时将默认 perl 的 IO 切换为 utf-8 是不是正确?【英文标题】:It is correct to switch the default perl's IO to utf-8 while using Plack and Middlewares?使用 Plack 和 Middlewares 时将默认 perl 的 IO 切换为 utf-8 是否正确? 【发布时间】:2012-06-16 05:59:58 【问题描述】:两个起点:
在his answer to Why does modern Perl avoid UTF-8 by default?tchrist 中指出了确保在Perl 中正确处理Unicode 所需的52 件事。答案显示了带有一些use
语句的样板代码。关于使用 Unicode 的一个类似问题是How to make "use My::defaults" with modern perl & utf8 defaults?
PSGI spec 在设计上是面向字节的。我有责任对所有内容进行编码/解码,因此对于 Plack 应用程序,正确的方法是对输出进行编码和对输入进行解码,例如:
use Encode;
my $app = sub
my $output = encode_utf8( myapp() );
return [ 200, [ 'Content-Type' =>'text/plain' ], [ $str ] ];
;
使用是否正确
use uni::perl; # or any similar
在 PSGI 应用程序和/或我的模块中?
uni::perl
将 Perl 的默认 IO 更改为 UTF-8,因此:
use open qw(:std :utf8);
binmode(STDIN, ":utf8");
binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");
这样做会破坏 Plack 或其中间件中的某些内容吗?或者是为 Plack 编写应用程序的唯一正确方法是在打开时显式编码/解码,所以没有 open
pragma?
【问题讨论】:
Plack 是写入 STDOUT 还是从 STDIN 读取?如果是这样,那几乎肯定是错误的(除非它们也是 Plack 中的错误)。我说“几乎”是因为在 Plack 中使用binmode
会让它不在乎。 PS - 现在您知道为什么默认情况下不这样做了;它会破坏东西。
我希望@miyagawa gurusan 会告诉更多.. :) 我理解为什么 utf8 不是默认的,但是,(IMO)新的 CPAN 模块应该使用“perl -CSDA”开发" 或考虑到env PERL_UNICODE
。而且宫川肯定会在日本环境中使用它,所以,应该知道正确的方法.. ;)
我认为您列出的“正确方法”已被破坏。 text/plain
需要一个字符集,以便对方知道字节代表什么以及如何解码它们。
@Ashley,是的 - 和thanx。该片段也有另一个错误($str vs $output)。但这与问题无关。
【参考方案1】:
在现代 GNU/Linux 系统上,您应该在全局范围内完全切换到 UTF-8。这意味着设置
LANG="xx_YY.UTF-8"
PERL_UNICODE=SDAL
PERL5OPT=-Mutf8
在您的/etc/environment
或/etc/sysconfig/i18n
或/etc/default/locale
或任何您的系统配置文件中。因为RHEL/Centos bug 我将/etc/environment
符号链接到sysconfig/i18n
。
依赖二进制输入的脚本应在 STDIN/OUT/ERR(?) 或 use open
pragma 上设置 binmode
,或者应使用 -C0
选项调用。
问题是某些DBD
驱动程序有问题,例如DBD::JDBC,必须手动设置utf8标志。
use Encode qw/_utf8_on/;
map _utf8_on $_; @strings;
【讨论】:
【参考方案2】:您真的不想在 Plack 上将 STDIN
/STDOUT
默认设置为 UTF-8 模式,因为您不知道它们是否会是二进制数据传输。例如。如果这些文件句柄是 FastCGI 协议连接器,它们将携带编码的二进制结构而不是 UTF-8 文本。因此,它们不得定义编码层,否则这些二进制结构将被破坏或视为无效而被拒绝。
【讨论】:
以上是关于使用 Plack 和 Middlewares 时将默认 perl 的 IO 切换为 utf-8 是不是正确?的主要内容,如果未能解决你的问题,请参考以下文章
python爬虫人门Scrapy框架之Downloader Middlewares
爬虫框架Scrapy之Downloader Middlewares