Почему мои Perl-тесты терпят неудачу с `use encoding 'utf8'`? - PullRequest
9 голосов
/ 29 января 2009

Я озадачен этим тестовым сценарием:

#!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.

Я использую Perl 5.8.8 в Mac OS X (системная версия).

Ответы [ 3 ]

18 голосов
/ 30 января 2009

Не используйте encoding прагму . Оно сломано. (Юрд Вальбур выступил с прекрасной речью, где он упомянул об этом на YAPC :: EU 2k8.)

Он делает как минимум две вещи одновременно, которые не принадлежат друг другу:

  1. Указывает кодировку для вашего исходного файла.
  2. Указывает кодировку для вашего файла ввода / вывода.

И чтобы добавить вред оскорблениям, он также делает № 1 в ломаной форме: он интерпретирует \xNN последовательности как не кодированные октеты, а не обрабатывает их как кодовые точки и декодирует их, не давая вам возможности выражать символы за пределами указанная вами кодировка и исходный код означают разные вещи в зависимости от кодировки. Это просто поразительно неправильно.

Пишите ваш исходный код только в ASCII или UTF-8. В последнем случае utf8 прагма является правильным для использования. Если вы не хотите использовать UTF-8, но хотите включить не-ASCII-символы, экранируйте или расшифруйте их явно.

И используйте слои ввода / вывода явно или установите их, используя open pragma для автоматического перекодирования ввода / вывода.

2 голосов
/ 02 декабря 2011

Документация Test :: More содержит исправление для этой проблемы, которое я только что обнаружил сегодня (и эта запись показывает выше в googles).

utf8 / "Широкий символ в печати"

Если вы используете utf8 или другие символы, не входящие в ASCII, с Test :: More, вы можете получить предупреждение «Широкий символ в печати». Используя 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";

Я добавил этот кусочек шаблонного кода в свой тестовый код, и он работает очаровательно.

2 голосов
/ 29 января 2009

Отлично работает на моем компьютере (на perl 5.10). Возможно, вам стоит попробовать заменить use encoding 'utf8' на use utf8.

Какую версию Perl вы используете? Я думаю, что более старые версии имели ошибки с UTF-8 в регулярных выражениях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...