Diferencias_Perl6_Perl5
- NOMBRE
- DESCRIPCIÓN
- Partes y Trozos
- Operadores
- Bloques y Declaraciones
- Expresiones Regulares y Reglas
- Subrutinas
- Formatos
- Paquetes
- Módulos
- Objetos
- Sobrecarga
- Funciones Internas
- Sin clasificar
- AUTORES
- TRADUCCIÓN AL CASTELLANO
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