2009-01-29 59 views
9

我疑惑这个测试脚本:为什么我的Perl测试失败,使用编码'utf8'`?

#!perl 

use strict; 
use warnings; 
use encoding 'utf8'; 
use Test::More 'no_plan'; 

ok('áá' =~ m/á/, 'ok direct match'); 

my $re = qr{á}; 
ok('áá' =~ m/$re/, 'ok qr-based match'); 

like('áá', $re, 'like qr-based match'); 

三个测试失败,但我期待的是use encoding 'utf8'既能字面ááqr基于正则表达式升级为utf8字符串,从而传递试验。

如果我删除use encoding行测试通过了预期,但我不知道为什么他们会在utf8模式下失败。

我在Mac OS X(系统版本)上使用perl 5.8.8。

回答

18

不要使用encoding pragma。它坏了。 (Juerd Waalboer给了他在YAPC ::欧盟2K8提到这个伟大的谈话。)

它做一次不属于在一起的至少两件事情:

  1. 它指定为源编码文件。
  2. 它为您的文件输入/输出指定编码。

,并增加伤害侮辱它也确实在一个破碎的方式#1:它重新诠释\xNN序列为未解码的八位字节,而不是对待他们像码点,并对其进行解码,防止您能够表达人物在您指定的编码之外,并根据编码使您的源代码表示不同的内容。这只是一个惊人的错误。

只用ASCII或UTF-8编写您的源代码。在后一种情况下,utf8 pragma是正确的使用。如果您不想使用UTF-8,但您确实想包含非ASCII字符,请明确地转义或解码它们。

并明确使用I/O层或使用open pragma将它们设置为使I/O自动正确转码。

+1

在过去我总是使用`use utf8`并且在去年左右的某个时候,我看到某处'使用utf8'被破坏,我应该使用`use encoding'utf8'`。 看来我需要再次重温整个问题...... 谢谢 – melo 2009-01-29 21:39:47

2

它可以在我的电脑上正常工作(在perl 5.10上)。也许你应该试着用use utf8替换use encoding 'utf8'

您使用的是哪个版本的perl?我认为旧版本在正则表达式中存在UTF-8错误。

+0

我也改变了`使用encoding'utf8'`来使用`utf8`,它在5.8.8 Linux上工作对我来说 – mpeters 2009-01-29 20:32:18

2

Test::More documentation包含此问题的修复程序,我刚刚发现(此条目在谷歌搜索结果中显示较高)。

UTF8 /“宽字符打印”

如果使用UTF-8或其他非ASCII字符,测试::更多你可能会得到一个警告“打印宽字符”。使用binmode STDOUT,“:utf8”不会修复它。 Test :: Builder(为Test :: More提供支持)复制STDOUT和STDERR。所以对它们的任何改变,包括改变他们的输出规则,都不会被Test :: More所看到。解决方法是直接更改Test :: Builder使用的文件句柄。

my $builder = Test::More->builder; 
binmode $builder->output,   ":utf8"; 
binmode $builder->failure_output, ":utf8"; 
binmode $builder->todo_output, ":utf8"; 

我加的样板此位为我的测试代码和它的作品魅力。

相关问题