Novedades en Perl 5.10
Con la aparición de la versión 5.10 del lenguaje Perl se incluyen unas cuentas novedades muy interesantes, muchas de ellas procedentes del trabajo en Perl 6, que ya pueden utilizarse en su mayoría en la versión 5.9.4.
Para usar las nuevas características se ha añadido una directiva llamada
feature
; además, como todas ellas tienen ámbito léxico, pueden ser activadas
y desactivadas a voluntad.
Como aparecen nuevas palabras reservadas en el lenguaje es necesario
habilitar su uso mediante la directiva feature
de forma similar a:
use feature qw(err ~~);
Nota: los apuntes aquí mencionados están tomados de fuentes creo que bastante fiables, pero yo no puedo comentar nada a nivel personal porque no los he usado todavía.
defined-or //
Este nuevo operador toma dos expresiones y si la de la izquierda está definida usa su valor; en caso contrario utiliza la expresión derecha.
$izquierda // $derecha;
que es equivalente a
defined $izquierda ? $izquierda : $derecha
Al parecer es bastante común el uso de expresiones como
$a = $valor1 || $valor2;
$b ||= 1;
para asegurarse de que una variable toma un valor concreto cuando falla el primero. El problema se encuentra cuando la primera expresión tiene un valor, pero éste evalúa lógicamente a falso debido a que es uno de estos: 0, '0' ó ''; en este caso debemos comprobar explícitamente si el valor está definido en lugar de evaluarlo lógicamente.
Al igual que los operadores ||
y &&
tienen equivalentes de menor prioridad
en las figuras de or
y and
respectivamente, el operador //
también tiene
su correspondencia de baja prioridad denominada err
.
$a = ( $b err $c );
say
say "Hola a todos";
Esta nueva función envuelve al print
de siempre y añade un salto de línea al
final de sus parámetros:
sub say {
print @_,"\n_";
}
Es más una ayuda para escribir menos y más deprisa, y evitar errores tontos con el salto de línea.
smart match ~~
El operador smart-match
es una versátil herramienta de comparación que puede
determinar mágicamente cómo comparar dos elementos.
use feature qw(~~ say);
if ($x ~~ @array) { say "$x está en la lista" }
if ($x ~~ /coco/) { say "coco está en el texto" }
if (@x ~~ /coco/) { say "coco está en la lista" }
if ($key ~~ %hash) { say "$key existe en el hash" }
if ($code_ref ~~ $arg) { say '$code_ref->($arg) return true' }
Es decir:
- Si se le pasa una lista y un escalar, efectúa una búsqueda de este último dentro del primero.
- Si se le pasa un patrón de búsqueda lo hace coincidir con el escalar ó la lista que está en el otro lado.
- Si se le pasa un
hash
y un escalar usa la funciónexist
para comprobar que esté dentro. - Si recibe una referencia a código y un parámetro, efectúa una llamada a dicho código, con dicho parámetro y comprueba que el resultado sea verdadero (sospecho que debo haberme perdido algo porque no entiendo bien la utilidad de ésto).
Este operador puede ser sobrecargado, como cualquier otro, y eso es algo que puede ser interesante en OOP también.
given-when
Este duo es la respuesta de Perl al operador switch
de otros lenguajes;
sustituye al módulo Switch, que está basado en un filtro de código
fuente y no siempre ha funcionado correctamente, especialmente con el
depurador.
use feature qw(say switch);
my $var = get_some_value();
given ( $var ) {
when ( /\D/ ) { say "Tiene que ser un número" }
when ( $_ == 1 ) { say "Es el uno" }
default { say "Es el número $_" }
}
given
almacena el valor de su argumento en la variable $_
automáticamente.
Tras eso Perl evalúa los bloques when
hasta que evalúa uno a verdadero, lo
ejecuta y termina; en caso de no encontrar ninguno, obviamente, ejecuta el
bloque default
si existe.
Ya que when
utiliza el operador smart-match
automáticamente es posible
simplificar bastante las comparaciones, por lo que podríamos ampliar el
ejemplo anterior con una búsqueda de números en una lista:
my @no_validos = ( 3, 6, 7, 9 );
my @repetidos = ();
given ( $var ) {
when ( /\D/ ) { say "Tiene que ser un número" }
when ( @repetidos ) { say "Este número está repetido " }
when ( @no_validos ) { say "Este número está maldito" }
when ( $_ == 1 ) { say "Es el uno" }
default {
say "Es el número $_";
push(@repetidos);
}
}
foreach-when
La claúsula when
también funciona muy bien con foreach
puesto que emite un
next
al terminar su bloque de código.
foreach (@lista_variada_de_cosas) {
when (/\w+/) { say "me vale como palabra" }
when (/\d+/) { say "me vale como número " }
}
directivas léxicas definidas por el usuario
FIXME
variables persistentes
Las variables persistentes (ó de estado) almacenan información entre las distintas llamadas a una función. La forma de conseguir este tipo de variables en la actualidad es con variables léxicas, confinadas dentro de un bloque y un función como en
{
my $accum = 0;
sub add_value {
$accum += shift;
return $accum;
}
}
El nuevo cualificador state
permite simplificar la síntaxis a:
use feature qw(state);
sub add_value {
state $accum = 0;
return $accum += shift;
}
parámetro -E
Este nuevo parámetro de llamada del intérprete Perl permite utilizar estas nuevas características sin necesidad de importarlas explícitamente dentro del módulo:
$ perl -E ' say "esto funciona" '
Habilita todas las nuevas posibilidades de la directiva feature
, y puede
usarse de la forma tradicional también:
$ perl -e ' use feature qw(say); say "esto funciona" '
$ perl -Mfeature=say -e ' say "esto funciona" '
constant folding
FIXME
UNIVERSAL::DOES
Dado que aún no tengo información práctica sobre esta nueva función, mejor copio el párrafo original que encontré por si a alguien le da alguna pista y, de paso, puede enseñarme algo, que estoy un poco perdido:
UNIVERSAL::DOES
is likeisa
, bu it doesn't depend on an inheritance relationship. I can check a class or an object to find out it behaves in a certain way, which Perl 5.10 call roles. A role is a grouping of special behaviors, mostly through method names i can call.
DOES
is similar asisa
, since i know that if it returns true the the object or class has a certain method even outside its@ISA
tree, whileDOES
does not worry about it where this method comes from.
Otras mejoras
La siguiente es una lista de mejoras y cambios de los que aún no tengo mucha información:
- Expresiones regulares más rápidas
- Mejor soporte de UTF-8
- Menor consumo de memoria
- Hashes de campos (field hashes)
- Aseveraciones (assertions)
- $AUTOLOAD se marca como
tainted
si el nombre del método también lo está. - Los filtros de código fuente pueden aplicarse también al array @INC
- Gestión de hilos mejorada
- Más mejoras para Windows
- Más documentación
Enlaces
- La presentación de Leon Brocard, Paul Fenwick y Audrey Tang en formato PDF.
- El ejemplar de primavera 2007 (Volumen 3, Ejemplar 2) de la revista The Perl Review a la que estoy subscrito.
- Documentación de
features
de la rama en desarrollo (por el momento) de Perl 5.94