2011-03-19 10 views
7

Tengo un problema con Perl y pragma de codificación.codificación de uso de Perl pragma rompiendo cadenas UTF

(I utilizar UTF-8 en todas partes, en la entrada, salida, los propios scripts de Perl. Yo no quieren usar otra codificación, nunca jamás.)

Sin embargo. Cuando escribo

binmode(STDOUT, ':utf8'); 
use utf8; 
$r = "\x{ed}"; 
print $r; 

veo la cadena "í" (que es lo que quiero - y lo que es U + 00ED carbón Unicode). Pero cuando agrego el pragma "use encoding" como este

binmode(STDOUT, ':utf8'); 
use utf8; 
use encoding 'utf8'; 
$r = "\x{ed}"; 
print $r; 

todo lo que veo es un carácter de cuadro. ¿Por qué?

Por otra parte, cuando agrego datos :: Dumper y dejar que el dumper imprimir la nueva cadena como esta

binmode(STDOUT, ':utf8'); 
use utf8; 
use encoding 'utf8'; 
$r = "\x{ed}"; 
use Data::Dumper; 
print Dumper($r); 

veo que Perl cambió la cadena-"\x{fffd}". ¿Por qué?

+1

Vea también: http://stackoverflow.com/questions/492838/why-do-my-perl-tests-fail-with-use-encoding-utf8 –

Respuesta

9

use encoding 'utf8' está roto. En lugar de interpretar \x{ed} como el punto de código U + 00ED, lo interpreta como el byte único 237 y luego intenta interpretarlo como UTF-8. Lo cual, por supuesto, falla, por lo que termina reemplazándolo con el carácter de reemplazo U + FFFD, literalmente " ".

sólo se adhieren con use utf8 para especificar que la fuente está en UTF-8, y binmode o la open pragma para especificar la codificación para los identificadores de archivo.

+0

Oh ... OK. No puedo afirmar que entiendo el motivo de la reinterpretación, pero hay cosas mucho más extrañas en Perl. Gracias –

+3

Por lo que puedo decir, la razón es que 'use encoding' fue diseñado para que la gente pudiera escribir' use encoding 'euc-jp'; $ r = "\ xF1 \ xD1 \ xF1 \ xCC"; 'y lo han interpretado" correctamente ". Pero eso significaría que tendría que escribir su cadena UTF-8 en el mismo estilo, como '$ r =" \ xC3 \ xAD ";'.Lo que luego se vuelve confuso cuando se combina con el soporte nativo de Perl para UTF-8 como '$ r =" \ x {200b} ";, los escapes con códigos 0x80-0xff se interpretan de forma diferente a escapes con códigos 0x100 y superiores. – Anomie

+3

Sí, el soporte de Perl para configuraciones regionales de 8 bits ('use encoding',' use locale') debe mantenerse en el otro extremo de un stick muy largo. – hobbs

5

Su código actual no necesita ni use encoding ni use utf8 para ejecutarse correctamente, de lo único que depende es de la capa de codificación en STDOUT.

binmode(STDOUT, ":utf8"); 
print "\xed"; 

es un programa completo igualmente válido que hace lo que desea.

use utf8 debe usarse solo si tiene UTF-8 en cadenas literales en su programa, por ej. si hubiera escrito

my $r = "í"; 

continuación use utf8 haría que esa cadena a ser interpretado como el único carácter U + 00ED en lugar de la serie de bytes C3 AD.

use encoding nunca debe usarse, especialmente por alguien a quien le gusta Unicode. Si desea cambiar la codificación de stdin/out, debe usar -C o PERLUNICODE o binmodearlos usted mismo, y si desea que otros identificadores se abren automáticamente con capas de codificación, debe useopen.

+0

hobbs: sí, tengo literales UTF-8 reales en mi código (en expresiones regulares). Gracias. –