Diferencias_Perl6_Perl5

NOMBRE

Perl6::Perl5::Differences -- Diferencias entre Perl 5 y Perl 6

DESCRIPCIÓN

Este documento está dirigido a los programadores de Perl 5 que se están iniciando en Perl 6 y quieren tener una referencia rápida de las diferencias principales. Puede encontrarse más detalles en la referencia del lenguaje en el enlace de más abajo.

Esta lista actualmente está incompleta.

Partes y Trozos

Identificadores

Cuando ponías:

my @frutas = ("manzana", "pera", "ciruela"); print $frutas[0], "\n";

Ahora es:

my @frutas = "manzana", "pera", "ciruela"; say @frutas[0];

También puedes utilizar el operador <>, que sustituye a qw():

my @frutas = <manzana pera ciruela>;

El identificador para un sólo elemento ha cambiado de $ a @. El identificador de una variable ahora es una parte de su nombre.

Lo mismo ocurre con los hashes:

say "Febrero tiene %dias{'Febrero'} días";

De nuevo, la forma corta es::

say "Febrero tiene %dias<Febrero> días";

Más detalles en http://feather.perl6.nl/syn/S02.html/#Names_and_Variables.

Las variables globales tienen dos identificadores

Sí, tienen dos. Es el segundo caracter del nombre de la variable. Para las globales es un *

Antes: $ENV{FOO} Ahora: %*ENV<FOO>

Más detalles en http://feather.perl6.nl/syn/S02.html/#Names_and_Variables.

Referencia a los elementos de un array o de un hash

Número de elementos de un array:

Antes: $#array+1 or scalar(@array) Ahora: @array.elems

Índice del último elemento de un array:

Antes: $#array Ahora: @array.end

Último elemento de un array:

Antes: $array[$#array] Ahora: @array[@array.end] @array[*-1] # cuidado con el asterisco

Más detalles en http://feather.perl6.nl/syn/S02.html#Built-In_Data_Types

Fuera los guiones bajos dobles

Antes Ahora ----- ----- __LINE__ $?LINE __FILE__ $?FILE __PACKAGE__ $?PACKAGE __END__ =begin END __DATA__ =begin DATA

Más detalles en http://feather.perl6.nl/syn/S02.html#double-underscore_forms_are_going_away. El identificador doble ? hace referencia a datos que se tienen en cuenta en tiempo de compilación.

Contextos

Todavía existen los tres contextos principales, void, item (formalmente scalar) y list. Además hay contextos especializados y operadores que fuerzan al contexto.

my @array = 1, 2, 3;

# contexto genérico del elemento my $a = @array; say $a.WHAT; # visualiza Array

# contexto string say ~@array; # "1 2 3"

# contexto numérico say +@array; # 3 # contexto booleano my $no-vacio = ?@array;

Comillas ' y guiones - están permitidos como parte de los identificadores si aparecen entre dos letras.

Operadores

La lista de cambios en los operadores puedes consultarla en http://feather.perl6.nl/syn/S03.html#Changes_to_Perl_5_operators y http://feather.perl6.nl/syn/S03.html#New_operators.

Algunos detalles:

Cambios en qw(); nueva forma de interpolación

Antes: qw(foo) Ahora: <foo>

Antes: ("foo", (split ' ', $bar), "bat") Ahora: <<foo $bar bat>>

Los operadores textuales ahora tienen modificadores que pueden utilizarse como en las expresiones regulares y sustituciones de Perl 5. Además, puedes definir los tuyos propios. Más detalles en http://feather.perl6.nl/syn/S03.html.

Los paréntesis () pasan de ser subscripts a sub llamadas, or eso en vez de qw(a b) puedes poner qw<a b> o qw[a b] (sino te gusta <a b>)).

Otros cambios importantes en los operadores

La concatenación de strings ahora se realiza con ~.

Las expresiones regulares se realizan con el operador inteligente (smart match) ~~. El operador de Perl 5 =~ ya no existe.

if "abc" ~~ m/a/ { ... }

| y & que eran operadores de inserción, ahora realizan uniones. Los operadores binarios AND y OR se dividen entre operadores string y numéricos, esto es ~& es un AND binario string, +& es un AND binario numérico, ~| es un OR binario string, etc.

Los paréntesis no crean listas, simplemente agrupan. Las listas se crean con el operador coma sin paréntesis:

my @lista = 1, 2, 3; # @lista tiene tres elementos

El operador flecha -> utilizado para dereferenciar no existe más. Como todo es un objeto y los corchetes hacen las llamadas a los métodos con una sintáxis elegante, directamente puedes utilizar el par de corchetes apropiados tanto para indexar como para llamar a un método:

my $aoa = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; say $aoa[1][0]; # 4

my $s = sub { say "hola" }; $s(); # o también $s.(); $lol.[1][0]

Bloques y Declaraciones

See http://feather.perl6.nl/syn/S04.html para ver la especificación completa de bloques y declaraciones en Perl 6.

No necesitas paréntesis en las condiciones de las estructuras de control

Antes: if ($a < $b) { ... } Ahora: if $a < $b { ... }

Lo mismo pasa con while, for, etc. Si quieres seguir utilizando paréntesis, asegúrate de poner un espacio después de if, porque sino, sería una sub llamada.

eval {} ahora es try {}

En un bloque, eval es reemplazado por try.

Antes: eval { # ... }; if ($@) { warn "oops: $@"; } Ahora: try { # ... CATCH { warn "uiss: $!" } }

CATCH da más flexibilidad controlando errores. Más detalles en http://feather.perl6.nl/syn/S04.html#Exception_handlers.

foreach evoluciona a for

Antes: foreach (@loquesea) { ... } Ahora: for @loquesea { ... }

Además, la forma de asignar algo que no sea $_ ha cambiado:

Antes: foreach my $x (@loquesea) { ... } Ahora: for @loquesea -> $x { ... }

En el caso de tener más elementos a la vez:

Antes: while (my($edad, $sexo, $ciudad) = splice @loquesea, 0, 3) { ... } Ahora: for @loquesea -> $edad, $sexo, $ciudad { ... }

(La versión for destruye el array, el resto de versiones no.)

Más detalles en http://feather.perl6.nl/syn/S04.html#The_for_statement y http://feather.perl6.nl/syn/S29.html#each.

for evoluciona a loop

Antes: for ($i=0; $i<10; $i++) { ... } Ahora: loop ($i=0; $i<10; $i++) { ... }

loop también puede utilizarse para bucles infinitos:

Antes: while (1) { ... } Ahora: loop { ... }

Expresiones Regulares y Reglas

Esto es una adaptación simple de las expresiones regulares de Perl5 a Perl6:

Antes: $str =~ m/^\d{2,5}\s/i Ahora: $str ~~ m:P5:i/^\d{2,5}\s/

El modificador :P5 se utiliza porque la sintaxis estándar de Perl6 es distinta. 'P5' permite la compatibilidad de la sintaxis con la de Perl5. Para realizar sustituciones:

Antes: $str =~ s/(a)/$1/e; Ahora: $str ~~ s:P5/(a)/{$0}/;

Ahora $1 comienza en $0. /e ya no existe y a cambio se utilizan las llaves incrustadas.

La especificación completa está en http://feather.perl6.nl/syn/S05.html. Consulta también:

La parte de Apocalypse, que justifica los cambios:

http://dev.perl.org/perl6/doc/design/apo/A05.html

Y la parte de Exegesis, que lo explica con más detalle:

http://dev.perl.org/perl6/doc/design/exe/E05.html

Subrutinas

Formatos

Las librerías externas controlan los formatos.

Paquetes

Módulos

Objetos

Perl 6 tiene un sistema "real" de objetos, con palabras claves para las clases, métodos y atributos. Los atributos públicos tienen el doble identificador ., los privados tienen el !.

class TuClase { has $!privado; has @.publico; # con acceso de escritura has $.algo is rw;

method haz_algo { if self.can('ladrar') { say "Cualquier cosa, perrito"; } } }

Cambios en la invocación de métodos, de -> a .

Antes: $objeto->metodo Ahora: $objeto.metodo

Distinción de referencias simbólicas de las referencias duras en las llamadas a métodos

Antes: $self->$metodo() Ahora: $self.$metodo() # referencia dura Ahora: $self."$metodo"() # referencia simbólica

Sobrecarga

Tanto las funciones internas como los operadores internos son multi subrutinas y métodos. Puedes definir tipos particulares a partir de ellos, y es tan simple como añadir las multi subrutinas y métodos apropiados. Si además quieres que estén disponibles globalmente, tienes que agregarlas al nombre de espacios GLOBAL:

multi sub GLOBAL::uc(TurcoStr $str) { ... }

# "sobrecarga" la concatenación de strings: multi sub infix:<~>(TurcoStr $nuestra, TurcoStr $suya) { ... }

Si quieres crear un prototipo de un tipo en particular, crea un método con el mismo nombre del tipo del cual quieras realizar el prototipo.

sub necesita_mitipo(MiTipo $x) { ... } class MiClase { ... # coerción al tipo MiTipo: method MiTipo { ... } }

necesita_mitipo(MiClase.new); # coerciona a MiTipo

Dando semántica a Hashes y Listas

Si quieres escribir clases cuyos objetos puedan asignarse a variables con el identificador @ necesitas utilizar el rol Positional. Igualmente, con el identificador % necesitas hacer el rol Associative. El identificador & implica ser Callable.

Los roles ofrecen los operadores postcircumfix:<[ ]> (Positional; para indexar arrays), postcircumfix:<{ }> (Associative) y postcircumfix:<()> (Callable). Puedes utilizar estos métodos para dar semánticas con sentido.

class OrderedHash does Associative { multi method postcircumfix:<{ }>(Int $index) { # pon aquí el código para acceder a un elemento del hash } multi method postcircumfix:<{ }>(*@@slice) { # pon aquí el código para acceder a partes del hash } ... }

my %hashOrdenado = HashOrdenado.new(); say %hashOrdenado{'a'};

Todos los detalles gore en http://feather.perl6.nl/syn/S13.html.

Cambios en el encadenamiento de operadores de comprobación de archivos

Antes: if (-r $archivo && -x _) {...} Ahora: if $archivo ~~ :r & :x {...}

Más detalles en http://feather.perl6.nl/syn/S03.html#Changes_to_Perl_5_operators%22%2F%22The_filetest_operators_now_return_a_result_that_is_both_a_boolean

Funciones Internas

Algunas de ellas se han eliminado. Más detalles en:

http://feather.perl6.nl/syn/S29.html#Obsolete

No hay referencias (o: todo es una referencia)

Los objetos Capture llenan el hueco de las referencias en Perl 6. Puedes pensar que son referencias "grandes", esto es, referencias que pueden capturar, no sólo la identidad actual de un sólo objeto, sino también las identidades relativas de varios objetos relacionados. En cambio, puedes pensar que las referencias de Perl 5 son una forma degenerada de Capture cuando quieras referirte sólo a un elemento.

Antes: ref $algo eq 'HASH' Ahora: $algo ~~ Hash

Antes: @nuevo = (ref $viejo eq 'ARRAY' ) ? @$viejo : ($viejo); Ahora: @nuevo = @$viejo;

Antes: %h = ( k => \@a ); Ahora: %h = ( k => @a );

Para pasar un argumento modificable por referencia:

Antes: sub foo {...}; foo(\$bar) Ahora: sub foo ($bar is rw); foo($bar)

La referencia "obsoleta" de antes tiene los detalles. Más información sobre Capture en http://feather.perl6.nl/syn/S02.html#Names_and_Variables, o en el FAQ de Capture, http://feather.perl6.nl/syn/Perl6%3A%3AFAQ%3A%3ACapture.html.

say()

Es una versión de print que añade automáticamente una línea nueva:

Antes: print "¡Hola, mundo!\n"; Ahora: say "¡Hola, mundo!";

Como esto lo haces muy a menudo, es una cosa útil que forma parte del lenguaje.

wantarray()

wantarray se sustituye por want.list. También están disponibles want.item y want.count, éste último da el número de valores esperados.

Te animamos a que tus objetos devuelvan cosas coherentes en cada posible contexto, en vez de preguntar por tu contexto de forma explícita.

Sin clasificar

Los elementos de un hash no asumen las comillas

Los elementos hash no asumen las comillas:

Antes: $dias{Febrero} Ahora: %dias{'Febrero'} O también: %dias<Febrero> O también: %dias<<Febrero>>

Los símbolos > y < siguen funcionando, pero ahora están más relacionadas con los bloques. De hecho lo que tienes es un bloque que devuelve el valor "Febrero". Estas formas son de hecho mecanismos de indicación utilizadas como subscripts (ver más abajo).

Las funciones internas ahora son métodos

La mayoría de las funciones internas ahora son métodos de clases internas como String, Array, etc.

Antes: my $longitud = length($string); Ahora: my $longitud = $string.chars;

Antes: print sort(@array); Ahora: print @array.sort; @array.sort.print;

Puedes seguir utilizando sort(@array) sino prefieres el idioma OO.

AUTORES

Kirrily "Skud" Robert, <skud@cpan.org>, Mark Stosberg, Moritz Lenz, Trey Harris

TRADUCCIÓN AL CASTELLANO

Desde la url original http://feather.perl6.nl/syn/Differences.html por Ramiro Encinas <ramiro.encinas@gmail.com> en agosto de 2009