为什么我的Perl测试会因`use encoding'utf8'而失败?

时间:2009-01-29 18:32:37

标签: perl testing utf-8

我对这个测试脚本感到困惑:

#!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的regexp升级为utf8字符串,从而通过测试。< / p>

如果我删除use encoding行,测试会按预期传递,但我无法弄清楚为什么它们会在utf8模式下失败。

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

3 个答案:

答案 0 :(得分:18)

不要使用encoding pragma。它坏了。 (Juerd Waalboer在YAPC :: EU 2k8上提到了这个问题。)

它至少有两件不属于一起的东西:

  1. 它指定源文件的编码。
  2. 它指定文件输入/输出的编码。
  3. 为了给侮辱增加伤害,它也会以破碎的方式排在第一位:它将\xNN序列重新解释为未解码的八位字节,而不是将它们视为代码点,并对它们进行解码,从而阻止您进行表达您指定的编码之外的字符,并使您的源代码根据编码意味着不同的东西。这只是一个惊人的错误。

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

    明确使用I / O图层或使用 open pragma 设置它们,以便I / O自动正确转码。

答案 1 :(得分:2)

它在我的电脑上工作正常(在perl 5.10上)。也许您应该尝试将use encoding 'utf8'替换为use utf8

您使用的是什么版本的perl?我认为旧版本在regexp中存在UTF-8错误。

答案 2 :(得分:2)

Test::More documentation包含此问题的修复程序,我今天刚刚发现(此条目在googles中显示较高)。

  

utf8 /“打印中的广角”

     

如果在Test :: More中使用utf8或其他非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";

我在测试代码中添加了这个样板文件,它很有魅力。