perlunifaq - Preguntas más frecuentes sobre Unicode en Perl
Esta lista de preguntas y respuestas sobre Unicode en Perl debe leerse después de leer perlunitut.
No. Y este documento no contiene preguntas y respuestas sobre Unicode.
Perl incluye una interfaz que abstrae todas las codificaciones de caracteres compatibles; este documento es en realidad un tutorial genérico de Encode con las preguntas más frecuentes sobre Encode. Pero muchas personas piensan que Unicode es algo especial y mágico. Como no quiero que se sientan defraudadas, he decidido clasificar este documento como un tutorial de Unicode.
Encode
Para averiguar cuáles son las codificaciones de caracteres admitidas por Perl, ejecute:
perl -MEncode -le "print for Encode->encodings(':all')"
Si puede, actualice a la versión más reciente; debe usar como mínimo la versión 5.8.1. En el tutorial y en las preguntas más frecuentes se supone que usa la versión más reciente.
5.8.1
También debe comprobar los módulos y actualizarlos si es necesario. Por ejemplo, HTML::Entities requiere la versión >= 1.32 para funcionar correctamente, aunque esto no se indica en el registro de cambios.
Bueno, aparte de usar binmode $fh, no debe darles ningún tratamiento especial (la función binmode es necesaria para evitar que, en sistemas Win32, Perl convierta los caracteres de fin de línea).
binmode $fh
No obstante, debe evitar combinar cadenas de texto con cadenas binarias. Si necesita texto en una secuencia binaria, codifique las cadenas de texto con la codificación adecuada y después únalas con cadenas binarias. Vea también: "¿Qué pasa si no descodifico?".
Siempre que haya intercambio de texto con alguna entidad externa al proceso de perl, como una base de datos, un archivo de texto, un socket u otro programa (aunque dicha entidad externa también se haya programado en Perl).
Siempre que la cadena binaria codificada se use junto con una cadena de texto, Perl supondrá que la cadena binaria se codificó con ISO-8859-1 (también llamada latin-1). Si la codificación no es latin-1, el resultado de la conversión de los datos no será lo que se esperaba. Por ejemplo, si la codificación es UTF-8, los bytes individuales de los caracteres multibyte se verán como caracteres independientes y se volverán a convertir a UTF-8. Esta codificación doble es similar a la codificación doble de HTML (>) o de URI (%253E).
>
%253E
Se produce una descodificación implícita sin aviso, denominada "promoción". Es posible que este nombre sugiera algo positivo, pero es mejor evitar que suceda.
La cadena de texto se enviará con los bytes del formato interno de Perl. En algunos casos Perl le mostrará un mensaje amistoso para avisarle de que está haciendo algo mal:
Wide character in print at ejemplo.pl line 2.
Como el formato interno suele ser UTF-8, es difícil detectar estos errores (puesto que normalmente la codificación deseada es UTF-8). Pero no sea perezoso; no debe basarse en el hecho de que el formato interno de Perl es UTF-8. Codifique explícitamente para evitar errores extraños y para que los programadores que van a mantener el código vean que ha pensado en todo.
Si todos los datos de un determinado identificador de archivo se codifican exactamente de la misma manera, puede ordenar al sistema de entrada/salida de Perl que descodifique todo automáticamente mediante la capa encoding. Si hace esto, no se olvidará de volver a descodificar o codificar cosas que usan el identificador de archivo con una capa.
encoding
Puede aplicar esta capa al abrir el archivo con open:
open
open my $fh, '>:encoding(UTF-8)', $archivo; # codificación automática al escribir open my $fh, '<:encoding(UTF-8)', $archivo; # descodificación automática al leer
O bien, si ya tiene un identificador de archivo abierto:
binmode $fh, ':encoding(UTF-8)';
Algunos controladores de base de datos para DBI también pueden codificar y descodificar automáticamente, pero a veces esta funcionalidad está limitada a la codificación UTF-8.
Haga lo que pueda para averiguar cuál es la codificación; adivínela, si no queda más remedio (y no olvide agregar un comentario para documentar su conjetura).
Puede abrir el documento en un navegador web y probar varios juegos o codificaciones de caracteres hasta confirmar visualmente que se ven bien todos los caracteres.
No existe una manera fiable de detectar automáticamente la codificación, por lo que es mejor enseñar a las personas que le suministran datos a indicar el juego de caracteres utilizado.
Por supuesto. Si el código fuente está codificado como UTF-8, puede indicarlo con el pragma use utf8:
use utf8
use utf8;
Esto no afecta ni a la entrada ni a la salida de datos. Solo influye en la manera de leer el código fuente. Puede usar Unicode en literales de cadena, en identificadores (aunque deben ser "caracteres de palabra" compatibles con \w) e incluso en delimitadores personalizados.
\w
No, el procesamiento de Unicode en Data::Dumper es correcto. Algunas personas se han quejado de que no restaura la marca UTF8 cuando se vuelven a leer los datos con eval. Sin embargo, no se debe mirar la marca, y no hay ninguna razón para que Data::Dumper sea una excepción a esta norma.
eval
Lo que sucede es esto: cuando Perl lee un literal de cadena, mantendrá una codificación de 8 bits mientras pueda (aunque la codificación interna de la cadena podría ser UTF-8 originalmente, cuando se volcó). Si se agregan otros caracteres a la cadena de texto y Perl tiene que renunciar a esta codificación, "promueve" la cadena a UTF-8 sin avisar.
Si codifica correctamente las cadenas para la salida, no tiene que preocuparse por esto, y puede aplicar eval a los datos volcados, como siempre.
Desde Perl 5.14 (y, de forma parcial, desde Perl 5.12), solo tiene que agregar use feature 'unicode_strings' al principio del programa. En su ámbito léxico, este problema no debería producirse. También se habilita automáticamente con use feature ':5.12' o use v5.12, o si se utiliza -E en la línea de comandos de Perl 5.12 o una versión posterior.
use feature 'unicode_strings'
use feature ':5.12'
use v5.12
-E
Esto se hace así para evitar que dejen de funcionar programas antiguos, que se basan en el funcionamiento anterior a la creación de Unicode. Esos programas antiguos solo usaban el juego de caracteres ASCII, por lo que es posible que no funcionen con otros caracteres. Si una cadena está codificada en UTF-8, Perl supone que el programa está preparado para trabajar con Unicode, pero si la codificación es otra, Perl supone que solo se desea usar ASCII por lo que los caracteres que no sean ASCII no se reconocerán como lo que serían en Unicode. use feature 'unicode_strings' indica a Perl que debe tratar todos los caracteres como Unicode, independientemente de si la cadena está codificada como UTF-8 o no, lo que evita el problema.
Sin embargo, en versiones anteriores de Perl, o si pasa cadenas a subrutinas fuera del ámbito del pragma feature, puede forzar el uso de reglas Unicode cambiando la codificación a UTF-8 mediante utf8::upgrade($string). Esto se puede aplicar de manera segura a cualquier cadena, puesto que comprueba si una cadena ya se ha promovido y, en caso afirmativo, no la modifica.
feature
utf8::upgrade($string)
Encontrará una descripción más detallada en Unicode::Semantics (disponible en CPAN).
Vea la respuesta a la pregunta anterior.
No se puede. Hay quien usa la marca UTF8 para esto, pero es un uso incorrecto que hace que parezca que hay errores en módulos que funcionan correctamente, como Data::Dumper. La marca no debe utilizarse para este fin, ya que se desactiva cuando se usa una codificación de 8 bits (de manera predeterminada, ISO-8859-1) para almacenar la cadena.
De esto debe encargarse el programador. Podría usar una notación "húngara" como ayuda.
Primero debe convertir la cadena de bytes con la codificación A en una cadena de texto y después la cadena de texto en una cadena de bytes con la codificación B:
my $cadena_texto = decode('A', $cadena_A); my $cadena_B = encode('B', $cadena_texto);
También puede omitir la parte de la cadena de texto y pasar directamente de una codificación binaria a otra:
use Encode qw(from_to); from_to($cadena, 'A', 'B'); # cambia el contenido de $cadena
o dejar que la descodificación y la codificación automáticas se encarguen de hacer la conversión:
open my $fh_A, '<:encoding(A)', 'ejemplo.A.txt'; open my $fh_B, '>:encoding(B)', 'ejemplo.B.txt'; print { $fh_B } $_ while <$fh_A>;
decode_utf8
encode_utf8
Ofrecen una sintaxis alternativa a decode('utf8', ...) y encode('utf8', ...).
decode('utf8', ...)
encode('utf8', ...)
Término utilizado para designar caracteres que ocupan más de un byte.
La advertencia de Perl "Wide character in ..." (Carácter ancho en...) se debe a la presencia de un carácter de este tipo. Si no se especifica una capa de codificación, Perl intenta que cada carácter ocupe un solo byte. Si no lo consigue, emite esta advertencia (si las advertencias están habilitadas), y utiliza datos codificados como UTF-8.
Para evitar esta advertencia y evitar la mezcla de distintas codificaciones de salida en una sola secuencia, especifique siempre una codificación explícitamente (por ejemplo, con una capa de entrada/salida):
binmode STDOUT, ":encoding(UTF-8)";
A menos que tenga que trabajar con los componentes internos o depurar cosas extrañas, olvídese de la marca UTF8. Esto significa que es muy probable que nunca tenga que usar is_utf8, _utf8_on y _utf8_off.
is_utf8
_utf8_on
_utf8_off
La marca UTF8, conocida también como SvUTF8, es una marca interna que indica que la representación interna actual es UTF-8. Sin esta marca, se supone que dicha representación es ISO-8859-1. Perl realiza la conversión entre estas codificaciones automáticamente. (En realidad, generalmente Perl supone que la representación es ASCII; vea la sección "¿Por qué algunas veces las clases de caracteres de expresiones regulares solo detectan caracteres ASCII?" anterior).
Resulta que uno de los formatos internos de Perl es UTF-8. Como Perl no se calla nada, esto es de dominio público. Y crea muchas confusiones. Es mejor imaginar que el formato interno es alguna codificación desconocida y acostumbrarse a codificar y descodificar explícitamente siempre.
use bytes
No lo use. No tiene sentido trabajar con bytes en una cadena de texto o trabajar con caracteres en una cadena de bytes. Realice las conversiones apropiadas (mediante descodificación o codificación) y todo saldrá bien: contará caracteres para los datos descodificados y bytes para los datos codificados.
use bytes suele ser un intento fallido de hacer algo útil. Olvide que existe.
use encoding
No lo use. Por desgracia, este pragma supone que la codificación utilizada en el entorno del programador es la misma que la utilizada en el entorno del usuario. Utilizará la misma codificación para el código fuente que para STDIN y STDOUT. Cuando se copia un programa a otro equipo, el código fuente no cambia, pero podría cambiar el entorno STDIO.
Si necesita utilizar caracteres que no pertenezcan a ASCII en el código fuente, codifíquelos como UTF-8 y use el pragma use utf8.
Si necesita establecer la codificación para STDIN, STDOUT y STDERR basándose, por ejemplo, en la configuración regional del usuario, use el pragma use open.
use open
:encoding
:utf8
Como UTF-8 es uno de los formatos internos de Perl, a menudo puede omitir el paso de codificar o descodificar, y manipular la marca UTF8 directamente.
En lugar de utilizar :encoding(UTF-8), puede usar simplemente :utf8, omitiendo así el paso de codificación cuando los datos ya están representados internamente como UTF8. Esto está aceptado universalmente como una práctica fiable al escribir, pero puede ser peligroso al leer, ya que crea una incoherencia interna cuando hay secuencias de bytes no válidas. El uso de :utf8 para la entrada puede permitir infracciones de seguridad en algunos casos, por lo que se recomienda usar :encoding(UTF-8) en su lugar.
:encoding(UTF-8)
En lugar de decode y encode, puede usar _utf8_on y _utf8_off, pero esto se considera poco elegante. En particular, el uso de _utf8_on puede resultar peligroso, por las mismas razones que el uso de :utf8.
decode
encode
Existen algunos métodos abreviados para scripts de una línea (one-liners); vea la descripción del modificador -C en perlrun.
UTF-8
utf8
UTF-8 es el estándar oficial. utf8 es la manera que tiene Perl de mostrarse liberal al procesar la entrada. Si tiene que comunicarse con algo que no es tan liberal, es posible que sea mejor utilizar UTF-8. Sin embargo, si tiene que comunicarse con algo que es demasiado liberal, puede que tenga que utilizar utf8. Encontrará información detallada en Encode.
Internamente, UTF-8 se denomina utf-8-strict. En este tutorial se usa siempre UTF-8, incluso para los casos en que se use utf8 internamente, ya que esta distinción puede resultar difícil de apreciar y además suele ser irrelevante.
utf-8-strict
Por ejemplo, se puede usar utf8 para códigos de carácter que no existen en Unicode, como 9999999, pero si los codifica en UTF-8, obtendrá caracteres sustitutos de manera predeterminada (vea la sección "Handling Malformed Data" de Encode para obtener información sobre otras maneras de abordar este problema).
Bueno, ya que insiste: el "formato interno" es utf8, no UTF-8 (cuando no es otra codificación).
Eso es una buena señal, ya que no debe esperar que el formato interno tenga una codificación específica. Pero para que no se quede con la duda, debe saber que, de manera predeterminada la codificación del formato interno es ISO-8859-1 (latin-1) o utf8, en función del historial de la cadena. En plataformas EBCDIC la codificación puede ser distinta a las mencionadas.
Perl sabe cómo se ha almacenado la cadena internamente, y usará ese conocimiento al codificar. En resumen: no intente averiguar cuál es la codificación interna de una cadena determinada; solo tiene que codificarla con la codificación que desee.
Juerd Waalboer <#####@juerd.nl>
perlunicode, perluniintro, Encode
Joaquín Ferrero (Tech Lead)
Enrique Nell (Language Lead)
To install POD2::ES, copy and paste the appropriate command in to your terminal.
cpanm
cpanm POD2::ES
CPAN shell
perl -MCPAN -e shell install POD2::ES
For more information on module installation, please visit the detailed CPAN module installation guide.