2009-01-29 11 views
9

estoy desconcertado con esta escritura de la prueba:¿Por qué mis pruebas Perl fallan con `use encoding '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'); 

Las tres pruebas fallan, pero esperaba que el use encoding 'utf8' mejoraría tanto el literal áá y las expresiones regulares qr basados ​​en cadenas UTF8, y así pasar el pruebas.

Si elimino la línea use encoding las pruebas pasan como se esperaba, pero no puedo entender por qué fallarían en el modo utf8.

Estoy usando perl 5.8.8 en Mac OS X (versión del sistema).

Respuesta

18

No utilice encoding pragma. Esta roto. (Juerd Waalboer dio una gran charla donde mencionó esto en 2k8 YAPC :: UE.)

Lo hace por lo menos dos cosas a la vez que no pertenecen juntos:

  1. Se especifica una codificación de la fuente archivo.
  2. Especifica una codificación para la entrada/salida de su archivo.

Y para agregar heridas a los insultos Tampoco # 1 de una manera rota: reinterpreta \xNN secuencias como octetos no decodificados en lugar de tratarlos como puntos de código, y los decodifica, que le impide ser capaz de expresar caracteres fuera de la codificación especificada y hacer que su código fuente tenga diferentes significados según la codificación. Eso es asombrosamente erróneo.

Escriba su código fuente en ASCII o UTF-8 solamente. En el último caso, utf8 pragma es lo correcto para usar. Si no desea usar UTF-8, pero desea incluir charcters que no sean ASCII, descárguelos o decodifíquelos explícitamente.

Y use las capas de E/S explícitamente o configúrelas usando open pragma para que las E/S se transcodifiquen automáticamente.

+1

En el pasado siempre usaba 'use utf8' y en algún momento del año pasado más o menos, vi en algún lugar que 'use utf8' estaba roto y debería usar' use encoding 'utf8''. Parece que necesito volver a visitar todo el problema otra vez ... Gracias – melo

2

Funciona bien en mi computadora (en Perl 5.10). Tal vez deberías intentar reemplazar ese use encoding 'utf8' con use utf8.

¿Qué versión de perl estás usando? Creo que las versiones anteriores tenían errores con UTF-8 en expresiones regulares.

+0

También cambié 'use encoding 'utf8'' to' use utf8' y funcionó para mí en 5.8.8 Linux – mpeters

2

El Test::More documentation contiene una solución para este problema, que acabo de encontrar hoy (y esta entrada muestra más arriba en los googles).

UTF-8/"carácter ancho en la impresión"

Si utiliza caracteres no ASCII UTF8 o de otro tipo con Test :: Más puede obtener un "carácter ancho en la impresión" de advertencia. Usando binmode STDOUT, ": utf8" no lo arreglará. Test :: Builder (que potencia Test :: More) duplica STDOUT y STDERR. Así que cualquier cambio en ellos, incluido el cambio de sus disciplinas de salida, no se verá en Test :: More. La solución alternativa es cambiar los manejadores de archivos usados ​​por Test :: Builder directamente.

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

que añade este fragmento de texto modelo a mi código de prueba y funciona a las mil maravillas.

Cuestiones relacionadas