Considere el siguiente programa:
lhp@nereida:~/Lperl/src/testing$ cat -n useutf8_1.pl
1 #!/usr/local/bin/perl -w
2 use strict;
3
4 my $x = 'áéíóúñ€';
5 print "$x\n";
6 print length($x)."\n";
Cuando lo ejecutamos obtenemos la salida:
lhp@nereida:~/Lperl/src/testing$ useutf8_1.pl áéíóúñ€ 15Perl tiene dos modos de procesamiento de datos: el modo byte y el modo carácter. El modo por defecto es el modo byte. Este modo es conveniente cuando se trabaja con ficheros binarios (p. ej. una imagen JPEG) y con texto codificado con un código que requiere un sólo byte por carácter como es el caso de Latin 1.
En efecto, la cadena 'áéíóúñ€'
- que es una cadena unicode codificada en UTF-8 -
tiene una longitud de 15 bytes. El asunto es que
no es lo mismo la longitud en bytes que la longitud en caracteres cuando nos salimos de ASCII
y Latin1. Si queremos
que length devuelva la longitud en caracteres usemos utf8 :
lhp@nereida:~/Lperl/src/testing$ cat -n useutf8_2.pl
1 #!/usr/local/bin/perl -w
2 use strict;
3 use utf8;
4
5 my $x = 'áéíóúñ€';
6 print "$x\n";
7 print length($x)."\n";
Al ejecutar obtenemos la longitud en caracteres:
lhp@nereida:~/Lperl/src/testing$ useutf8_2.pl Wide character in print at ./useutf8_2.pl line 6. áéíóúñ€ 7Ahora
length retorna la longitud en caracteres.
Obsérvese el mensaje de advertencia. Si queremos asegurar el buen funcionamiento
de la salida por STDOUT con caracteres codificados en UTF-8
debemos
llamar a binmode sobre STDOUT con la capa ':utf8':
lhp@nereida:~/Lperl/src/testing$ cat -n useutf8_3.pl
1 #!/usr/local/bin/perl -w
2 use strict;
3 use utf8;
4 binmode(STDOUT, ':utf8');
5
6 my $x = 'áéíóúñ€';
7 print "$x\n";
8 print length($x)."\n";
El mensaje de advertencia desaparece:
lhp@nereida:~/Lperl/src/testing$ useutf8_3.pl áéíóúñ€ 7Usando la opción
-C del intérprete Perl se puede conseguir el mismo resultado:
lhp@nereida:~/Lperl/src/testing$ perl useutf8_1.pl áéíóúñ€ 15 lhp@nereida:~/Lperl/src/testing$ perl -Mutf8 -COE useutf8_1.pl áéíóúñ€ 7
Lea perldoc perlrun
para mas información sobre estas
opciones:
As of 5.8.1, the "-C" can be followed either by a number or a list of option
letters. The letters, their numeric values, and effects are as follows;
listing the letters is equal to summing the numbers.
I 1 STDIN is assumed to be in UTF-8
O 2 STDOUT will be in UTF-8
E 4 STDERR will be in UTF-8
S 7 I + O + E
i 8 UTF-8 is the default PerlIO layer for input streams
o 16 UTF-8 is the default PerlIO layer for output streams
D 24 i + o
A 32 the @ARGV elements are expected to be strings encoded in UTF-8
L 64 normally the "IOEioA" are unconditional,
the L makes them conditional on the locale environment
variables (the LC_ALL, LC_TYPE, and LANG, in the order
of decreasing precedence) -- if the variables indicate
UTF-8, then the selected "IOEioA" are in effect
En Perl las cadenas tienen un flag que indica si la representación interna
de la cadena es utf-8.
La función is_utf8 de utf8
permite conocer
si una cadena esta almacenada internamente como utf-8:
pl@nereida:~/Lperltesting$ cat -n is_utf8.pl
1 #!/usr/local/lib/perl/5.10.1/bin/perl5.10.1 -w -COE
2 use strict;
3 use utf8;
4
5 my $x = 'áéíóúñ€';
6 my $y = 'abc';
7 my $z = 'αβγδη';
8 print "$x is utf8\n" if utf8::is_utf8($x);
9 print "$y is utf8\n" if utf8::is_utf8($y);
10 print "$z is utf8\n" if utf8::is_utf8($z);
Al ejecutar produce la salida:
pl@nereida:~/Lperltesting$ ./is_utf8.pl áéíóúñ€ is utf8 αβγδη is utf8
Casiano Rodríguez León
