Junio 2016
"Las cosas sencillas deberían continuar siendo sencillas, las cosas difíciles deberían ser más fáciles, y las cosas imposibles deberían ser difíciles"
Hay más de una forma para hacerlo.
En Perl 6, decidimos que sería mejor arreglar el lenguaje que arreglar al usuario. "Larry Wall"
Perl 6 debe ser lo suficientemente maleable como para evolucionar a Perl 7, el lenguaje perfecto. Este imperativo darwiniano implica el soporte a múltiples plataformas (por debajo) y a múltiples sintaxis (por encima). "Larry Wall"
Comentarios multilínea estilo secciones Pod:
say "Hola";
=comment
línea 1
línea 2
=cut
say "Adiós";
my $saludo = "Ho" ~ "la";
say $saludo;
# Hola
$saludo ~= " y adiós.";
say $saludo;
# Hola y adiós.
my @array = 1, 2, 3;
my $a = @array; # $a contiene un solo array
say $a;
[1 2 3]
La clase Mu es la raíz de la jerarquía de tipos de Perl 6. Mu tiene el valor más indefinido que pueda existir en Perl 6. De ella solo heredan las clases Any y Junction.
La clase Any hereda de Mu y es la superclase base por defecto de la mayoría de las clases incorporadas y para crear nuevas clases. De ella heredan directamente unas 70 clases.
El método .defined indica si el objeto está definido o no:
say .defined;
False
say "".defined;
True
El método .WHAT indica la clase a la que pertenece el objeto:
say .WHAT;
(Any)
"".WHAT;
(Str)
1.WHAT;
(Int)
El método ^.methods indica los métodos disponibles:
"x".^methods;
(BUILD Int Num chomp chop pred ...
my $nombre = 'Juan De Dios';
say $nombre.uc;
say $nombre.chars;
say $nombre.flip;
JUAN DE DIOS
12
soiD eD nauJ
my $edad = 17;
say $edad.is-prime;
True
Es un tipo que puede tratar a su valor como texto o como número:
my Cool $var = 32;
say $var.chars;
say $var * 2;
2
64
subset Coordenada of Real where -1.0 .. 1.0;
my Coordenada $x = 2; # Type check failed...
my @array = 0, 1, 2;
sub es-cero($x) { return True if $x == 0; }
if es-cero(any @array) { say "Hay un 0"; }
Hay un 0
my @array = 0, 0, 0;
sub es-cero($x) { return True if $x == 0; }
if es-cero(all @array) { say "Todos son 0"; }
Todos son 0
my $listaperezosa = (1 ... 10);
say $listaperezosa;
(1 2 3 4 5 6 7 8 9 10)
my $listaperezosa = (0, 2 ... 10);
say $listaperezosa;
(0 2 4 6 8 10)
my $listaperezosa = (0, { $_ + 3 } ... 12);
say $listaperezosa;
(0 3 6 9 12)
my $lista = (1 ... 10).eager;
say $lista;
(1 2 3 4 5 6 7 8 9 10)
No son necesarios los paréntesis:
if $x == 0 {
say "El valor es cero.";
}
Se puede invertir la condición:
say "El valor es cero." if $x == 0;
Es lo contrario de IF:
my $x = 1;
unless $x == 0 {
say "El valor no es cero.";
}
No soporta else.
Múltiples condiciones:
my $x = 0;
given $x {
when $_ == 0 { say "Es cero"; }
when $_ == 1 { say "Es uno"; }
default { say "Ni cero ni uno"; }
}
También funciona en solitario:
my $saludo = "hola";
given $saludo { .say; }
hola
Comprueba si la variable está definida:
my Int $x;
with $x { say 'Definida'; }
else { say 'No definida'; }
Es un prejijo que devuelve True o False:
my $x = so 1; # $x = True
my $y = so 0; # $y = False
También funciona como método:
1.so; # True
0.so; # False
Recorre una serie de valores proporcionados:
for 1..10 -> $x {
say $x;
}
Puede leer líneas de un fichero de forma perezosa:
for "test.pl6".IO.lines {
say $_;
}
Incorpora la parametrización de C para el FOR:
loop (my $x=0; $x < 10; $x++) {
say $x;
}
Bucles infinitos:
loop {
say "¡Hasta el infinito y más allá!";
}
sub f ($x?) {
with $x { say $x; }
else { say "Sin argumento"; }
}
f;
f "Hola";
Sin argumento
Hola
sub f ($x=1) {
say $x;
}
f;
f 2;
1
2
multi f ($x, $y) { say $x ~ $y; }
multi f ($x, $y, $z) { say $x ~ $y ~ $z; }
f "U", 2;
f "U", 2, "!";
U2
U2!
sub cuadrado ($x) returns Int {
return $x ** 2;
}
say "2 al cuadrado es igual a " ~ cuadrado(2);
say "1.2 al cuadrado es igual a " ~ cuadrado(1.2);
2 al cuadrado es igual a 4
Type check failed for return value; expected Int but got Rat (1.44)
Otra forma de hacerlo:
sub cuadrado ($x --> Int) {
sub cuadrado($x) {
return $x ** 2;
}
sub f (&cuadrado) {
say "El cuadrado de 2 es: " ~ &cuadrado(2);
}
f (&cuadrado);
El cuadrado de 2 es: 4
sub cuadrado($x) {
return "El cuadrado de $x es " ~ $x ** 2;
}
my $x = cuadrado(2);
say $x;
El cuadrado de 2 es: 4
sub cuadrado($x) {
my $y = $x ** 2;
return sub { say "El cuadrado de $x es $y" };
}
my $resultado = cuadrado(2);
$resultado();
El cuadrado de 2 es 4
my $cuadrado = -> $x { $x ** 2; }
say $cuadrado(9);
81
my $cuadrado = * ** 2; # lo mismo que -> $x { $x ** 2; }
say $cuadrado(9);
81
sub cuadrado ($x) { return $x ** 2; }
sub cubo ($x) { return $x ** 3; }
my $num = 2;
say $num.&cuadrado.&cubo;
64
Aplica una función a una serie de elementos:
my @array = <0 1 2 3 4 5 6 7 8 9 10>;
sub cuadrado($x) { return $x ** 2 };
say @array>>.&cuadrado;
[0 1 4 9 16 25 36 49 64 81 100]
Los ensamblajes y listas perezosas también forman parte de la programación funcional.
say @*ARGS; # todos los parámetros
say @*ARGS[0]; # el primer parámetro
print "Nombre: ";
my $nombre = get;
my $edad = prompt("Hola $nombre, dime tu edad: ");
say "No aparentas tener $edad años.";
my $f = open("data.txt");
say $f.lines; # lista perezosa con las líneas
$f.seek(2); # vuelve al caracter 2
for $f.lines -> $linea { say $linea; } # recorre desde el caracter 2
$f.close;
for "data.txt".IO.lines -> $linea { say $linea; }
my $texto = slurp "data.txt";
say $texto; # muestra el archivo tal cual
say $texto.lines; # lista perezosa con las líneas
my $f = open "data2.txt", :w;
$f.print("linea 1\n");
$f.say("línea 2");
$f.close;
spurt "data2.txt", "línea 1\nlínea 2\n";
say dir; say dir "/usr/bin";
mkdir "nueva-carpeta";
rmdir "nueva-carpeta";
"nombre-archivo-carpeta".IO.e; # comprueba la existencia
"nombre-archivo-carpeta".IO.d; # comprueba si es directorio
"nombre-archivo-carpeta".IO.f; # comprueba si es archivo
class Clase {
has $!var-privada;
has $.var-publica is rw;
has @!array-privado;
method modificar($var) { $!var-privada = $var; }
method agregar($var) { push @!array-privado, $var; }
method ver-privado { say $!var-privada; say @!array-privado; }
}
my $objeto = Clase.new(var-publica => "valor1");
say $objeto.var-publica;
$objeto.var-publica = "valor2";
say $objeto.var-publica;
$objeto.modificar("valor3");
$objeto.agregar("valor4");
$objeto.agregar("valor5");
$objeto.ver-privado;
valor1
valor2
valor3
[valor4 valor5]
class ClaseHija is ClasePadre {
method foo {...}
}
Si un método heredado de la clase padre tiene el mismo nombre que un método definido en la clase hija, prevalece el método de la clase hija.
class ClaseHija is ClasePadre is ClaseMadre{
method foo {...}
}
La resolución de varios métodos con el mismo nombre se realiza mediante el algoritmo C3.
Ejemplo de herencia múltiple de roles:
role RolPadre {
method habla($mensaje) { say $mensaje ~ " al padre." ; }
}
role RolMadre {
method habla($mensaje) { say $mensaje ~ " a la madre."; }
}
class ClaseHija does RolPadre does RolMadre {
method habla ($mensaje) {
self.RolMadre::habla($mensaje);
}
}
my $objeto = ClaseHija.new;
$objeto.habla("Hola");
Hola a la madre.
Cada elemento encontrado (tipo match) incluye otro array con los grupos de captura:
"abcdefghijk" ~~ m:g/bc(.)efg(.)ij/;
# el modificador :g busca todas las coincidencias
say $/[0][0]; # tipo match;
say $/[0][1].Str; # tipo String;
「d」
h
Ejecución de código en hilos independientes:
sub uno{ sleep 5; return "uno!"; }
sub dos{ sleep 10; return "dos!"; }
my $p1 = Promise.start( { uno } );
my $p2 = Promise.start( { dos } );
say await $p1, $p2;
Se crean tres hilos, uno para el proceso principal, otro para una promesa y otro para la otra. Transcurren 10 segundos y visualiza: (uno! dos!)
Se emiten tres eventos en distintos momentos y tap los recoge a tiempo real:
my $supply = supply {
for 1..3 -> $x {
sleep $x;
emit "Han transcurrido $x segundos";
}
}
say "Inicio";
$supply.tap( -> $r { say $r });
Inicio
Han transcurrido 1 segundos
Han transcurrido 2 segundos
Han transcurrido 3 segundos
Servidor web multihilo con react y whenever:
my $cabecera-http = qq{HTTP/1.1 200 OK
Content-Type: text/html;charset=utf-8
};
my $mensaje-respuesta = "¡Hola mundo!";
react {
whenever IO::Socket::Async.listen('localhost',3000) -> $conn {
whenever $conn.Supply -> $buf {
$conn.print: $cabecera-http ~ $mensaje-respuesta;
$conn.close;
}
}
}