Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 
Índice general » En Comunidad » Pasando el Rato » 6 primitivas de Perl 6 que no sabías que necesitabas Responder al tema
Nuevo tema


Página 1 de 1  [ 1 mensaje ] 
 
Nota 2010-07-25 17:08 @756
Avatar de Usuario
Administrador
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España
Mensajes: 10216
6 primitivas de Perl 6 que no sabías que necesitabas
.pick
Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
    say @mazo.pick();                   # escoge una carta, cualquier carta...

    say @mazo.pick(5);                  # mano de poker

    my @barajado = @mazo.pick(*);       # aquí, '*' significa 'sigue adelante'
                                        # Quiere decir que extraemos todas las cartas del mazo,
                                        # de forma aleatoria, y las guardamos en @barajado

    my @urna = <negra blanca blanca>;   # cuentas de colores, 1/3 negras, 2/3 blancas
    .say for @urna.pick(50, :replace);  # devolvemos a la urna la cuenta extraída
                                        # Quiere decir que hacemos 50 extracciones de cuentas de colores,
                                        # decimos de qué color es la bolita, y la devolvemos a la @urna


    for @urna.pick(*, :replace) {
        .say;                           # infinito extractor de cuentas de colores
    }

    say [+] (1..6).pick(4, :replace);   # Extrae cuatro números de la lista del 1 al 6, y nos da la suma de ellos

    class Enemigo {                                            # definimos la clase Enemigo
        method atacar-con-flechas  { say "piou piou piou"    } # con una serie de métodos,
        method atacar-con-espadas  { say "swish cling clang" } # que en realidad son estrategias
        method atacar-con-rayos    { say "sssSSS fwoooof"    } # de combate, usando nuestras armas,
        method atacar-con-camelia  { say "flap flap ¡RAWWR!" } # incluida nuestra mariposa más mortífera
    }

    my $selector = { .name ~~ /^ 'atacar-con-' / };            # expresión regular que define a los métodos de ataque
    given Enemigo.new -> $e {                                  # creamos un nuevo Enemigo, $e
        my $atacar-estrategia                                  # elegimos una estrategia de ataque
            = $e.^methods().grep($selector).pick();            # eligiendo al azar (pick()) de entre todos
                                                               # los métodos de Enemigo que sean para atacar

        $e.$atacar-estrategia;                                 # atacamos al enemigo con esa estrategia
    }
 


.classify
Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
    my @nombres = <Patrick Jonathan Larry Moritz Audrey>;
    say .key, "\t", ~.values              # ordenamos los nombres por número de caracteres
        for @nombres.classify( *.chars );

    # Salida:
    # 5       Larry
    # 6       Moritz Audrey
    # 7       Patrick
    # 8       Jonathan

    .say for slurp("README")\              # leemos todo el fichero
         .words()\                         # dividimos en una lista de palabras
         .classify( *.Str )\               # agrupamos las palabras según las veces que aparecen,
                                           # es decir, el primer elemento de la lista es la palabra,
                                           # y el segundo elemento es un array con todas las veces
                                           # que aparece en el texto
         .map({; .key => .value.elems })\  # lo convertimos a hash palabra => número de veces
         .sort( { -.value } )\             # ordenamos por esos valores, de forma descendente
         .[ ^10 ];                         # y nos quedamos con las 10 palabras más comunes

    class Estudiante {                     # Un estudiante
        has Str $.nombre;                  # que tiene un nombre
        has Int $.grado is rw;             # y una graduación
    }

    my Estudiantes @estudiantes = obtener-estudiantes();       # Obtenemos la lista de estudiantes
    for @estudiantes.classify( *.grado ).sort -> $grupo {      # Para todos ellos, los ordenamos por
                                                               # su nivel de graduación. $grupo es un
        say "Estos estudiantes tienen el grado $grupo.key():"; # hash cuya clave es el grado, y el valor
        say .nombre for $grupo.value.list;                     # la lista de estudiantes
    }
 


.sort
Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
# 1 si $a es mayor, -1 si $b es mayor, 0 si son iguales
$a <=> $b;

# ordenar estudiantes de acuerdo a su grado
@estudiantes.sort: -> $a, $b { $a.grado <=> $b.grado };

# lo mismo
@estudiantes.sort: { $^a.grado <=> $^b.grado };

# lo mismo
@estudiantes.sort: { .grado };

# lo mismo
@estudiantes.sort: *.grado;

# leg da -1, 0 o 1 de acuerdo a una ordenación léxico-gráfica
# 'leg' es para Str, 'cmp' es ahora un 'sort' independiente del tipo
$a leg $b;

# ordena estudiantes por nombre (orden Unicode)
@estudiantes.sort: { $^a.nombre leg $^b.nombre };

# lo mismo
@estudiantes.sort: *.nombre;

# no te preocupes, los cálculos son almacenados, por lo que no hay reevaluaciones
@elementos.sort: *.calculo-extensivo();

# ... que quiere decir que esto funciona (y es un buen barajado)
@mazo.sort: { rand }

# ... pero este es más lindo :)
@mazo.pick(*);
 


Sobrecargando operadores
Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
    sub infix:<±>($numero, $error) {    # definimos un operador infijo
        $numero - $error + rand * 2 * $error;
    }
    say 15 ± 5;                          # algo entre 10 y 20

    sub postfix:<!>($n) { [*] 1..$n }    # definimos un operador postfijo
    say 5!;                              # que calcula el factorial del número 5: 120

    class Physical::Unit {               # Definimos una clase, de unidades de física
        has Int $.kg = 0;                # estos atributos denotan la potencia de las unidades
        has Int $.m  = 0;                # por ej., $.kg == 2 significa que este objeto
        has Int $.s  = 0;                # tiene de unidades kg**2

        has Numeric $.carga;

                                         # Definimos la multiplicación con otra unidad física
        method multiplicar(Physical::Unit $otro) {
            Physical::Unit.new(
                :kg( $.kg + $otro.kg ),
                :m(  $.m + $otro.m   ),
                :s(  $.s + $otro.s   ),
                :carga( $.carga * $otro.carga )
            )
        }

                                         # Definimos la inversión
        method invertir() {
            Physical::Unit.new(
                :kg( -$.kg ), :m( -$.m ), :s( -$.s ),
                :carga( 1 / $.carga )
            )
        }

                                         # Definimos la conversión a cadena de caracteres
        method Str {
            $.carga
            ~ ($.kg ?? ($.kg == 1 ?? " kg" !! "kg**$.kg") !! "")
            ~ ($.m  ?? ($.m  == 1 ?? " m"  !! "m**$.m")   !! "")
            ~ ($.s  ?? ($.s  == 1 ?? " s"  !! "s**$.s")   !! "")
        }
    }

                                         # Definimos operadores postfijos
    sub postfix:<kg>(Numeric $carga) { Physical::Unit.new( :kg(1), :$carga ) }
    sub postfix:<m>(Numeric $carga)  { Physical::Unit.new( :m(1), :$carga  ) }
    sub postfix:<s>(Numeric $carga)  { Physical::Unit.new( :s(1), :$carga  ) }

    # Definimos varias combinaciones de multiplicación de unidades físicas
    # Notar cómo usamos ahora 'multi sub', para no ensombrecer el original infix:<*>
    multi sub infix:<*>(Physical::Unit $a, $b) {
        $a.clone( :carga($a.carga * $b) );
    }

    multi sub infix:<*>($a, Physical::Unit $b) {
        $b.clone( :carga($a * $b.carga) );
    }

    multi sub infix:<*>(Physical::Unit $a, Physical::Unit $b) {
        $a.multiplicar($b);
    }

    # y otras para la división
    multi sub infix:</>(Physical::Unit $a, $b) {
        $a.clone( :carga($a.carga / $b) );
    }

    multi sub infix:</>($a, Physical::Unit $b) {
        $b.invertir.clone( :carga($a / $b.carga) );
    }

    multi sub infix:</>(Physical::Unit $a, Physical::Unit $b) {
        $a.multiplicar($b.invertir);
    }

    # Ejemplos de uso
    say 5m / 2s;                         # 2.5 m s**-1
    say 100kg * 2m / 5s;                 # 40 kg m s**-1
 


infix:<Z>
Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
    # Z (el operador 'zip') significa "mezcla estas listas juntas"
    my @gustos = <picante dulce suave>;
    my @alimentos = <sopa patatas tofu>;
    @gustos Z @alimentos; # <picante sopa dulce patatas suave tofu>

    # » significa "llama al método por cada elemento"
    .say for @estudiantes».grado;                 # todos los grados

    for @estudiantes».nombre Z @estudiantes».grado -> $nombre, $grado {
        say "$nombre obtuvo este año un grado de $grado";
    }

    # Notar que la siguiente lista es infinita - funciona igualmente
    for @estudiantes».nombre Z (1..6).pick(*, :replace) -> $nombre, $dado {
        say "$nombre juego un $dado";
    }

    # puede también usar Z junto con dos listas con un operador infijo
    my @total-puntuaciones = @primera-puntuacion Z+ @segunda-puntuacion;

    # cadenas como claves; un número incremental de unos, como valores
    my %hash = @nombres Z=> 1 xx *;              # xx es el operador de repetición

    # numerar personas con números crecientes
    my %gente2numeros = @gente Z=> 1..*;

    # ¿no tienes un buen operador? ¡créate el tuyo propio!
    sub infix:<gusta>($amante, $amado) { "$amante está encariñado con $amado" }

    # notar como el operador infijo infix:<Zgusta> está disponible automáticamente
    my @relaciones = @amantes Zgusta @amados;
 


infix:<...>
Syntax: [ Download ] [ Hide ]
Using perl Syntax Highlighting
    1 ... $n                                    # enteros de 1 a $n
    $n ... 1                                    # y al revés

    1, 3 ... $n                                 # números impares hasta $n
    1, 3, ... *                                 # números impares
    1, 2, 4 ... *                               # potencias de dos
    map { $_ * $_ }, (1 ... *)                  # cuadrados

    1, 1, -> $a, $b { $a + $b } ... *           # fibonacci
    1, 1, { $^a + $^b } ... *                   # ídem
    1, 1, *+* ... *                             # ídem

    'Camelia', *.chop ... '';                   # todos los prefijos posibles de 'Camelia'

    # Ver http://blog.plover.com/CS/parentheses.html
    # para ver los principios que hay detrás de esto
    sub siguiente-parentesis-balanceado($s) {
        $s ~~ /^ ( '('+ ) ( ')'+ ) '(' /;
        [~] $s.substr(0, $/.from),
            "()" x ($1.chars - 1),
            "(" x ($0.chars - $1.chars + 2),
            ")",
            $s.substr($/.to);
    }

    my $N = 3;

    my $inicio = "()" x $N;
    my &paso = &siguiente-parentesis-balanceado;
    my $fin = "(" x $N ~ ")" x $N;

    for $inicio, &paso ... $fin -> $cadena {
        say $cadena;
    }

    # Salida:
    # ()()()
    # (())()
    # ()(())
    # (()())
    # ((()))


(Traducción del artículo de masak, del día 23 de julio en use.perl.org)

_________________
JF^D Perl programming


Responder al tema  [ 1 mensaje ] 

Reglas del Foro
No puedes abrir nuevos temas en este Foro
No puedes responder a temas en este Foro
No puedes editar tus mensajes en este Foro
No puedes borrar tus mensajes en este Foro
No puedes enviar adjuntos en este Foro

Publicidad

Socializa

Síguenos por Twitter

Suscríbete GRATUITAMENTE al Boletín de Perl en Español

Saltar a:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Traducción al español por Huan Manwë para phpbb-es.com
phpBB SEO