Este documento describe cómo instalar y configurar Perl en diferentes sistemas operativos, así como algunas herramientas de desarrollo integrado recomendadas para Perl. Explica los tipos de datos escalares en Perl, incluidos números, cadenas y cómo Perl convierte automáticamente entre tipos de datos. Finalmente, proporciona un pequeño ejemplo para ilustrar la conversión automática de tipos.
2. ¿Qué necesitamos?
Intérprete:
Linux: viene por defecto en todas las distribuciones
Unix: ...cualquier sistema UNIX que se precie lo incluye
Mac: viene en el sistema (como buen UNIX que es).
Alternativas
macports: http://goo.gl/k5HnD
Active Perl: http://goo.gl/V8R3h
Windows:
Active Perl: http://goo.gl/V8R3h
Cygwin: http://goo.gl/czYc5
3. ¿Qué necesitamos?
IDE:
Plugin de eclipse: http://goo.gl/RnAvo
Komodo (Comercial): http://goo.gl/rtnEi
Komodo Edit (open source): http://goo.gl/m1d0c
padre (linux y windows, en mac la instalación se puede
complicar por necesitarse un entorno de 32 bits): http://
goo.gl/jh6ca
vi, emacs, joe, gedit, kate... o cualquier editor de texto de
UNIX que soporte resaltado de sintaxis.
más información: perlfaq3 (http://goo.gl/QkJLL)
4. Nota curiosa: asemejar
la sintaxis de perl con las
¿Perl es fácil o difícil?
contracciones en inglés.
Perl es fácil de usar, pero “difícil” de aprender
while (<>) {
chomp;
print join("t", (split /:/)[0, 2, 1, 5] ), "n";
}
Una vez se maneja la sintaxis es un lenguaje muy
productivo:
con pocas líneas de texto se consiguen muchos
resultados
5. ¿Cuándo usar perl?
Vale para todo:
Desde pequeños prototipos o programas “rápidos” escritos
en 5 minutos
Hasta grandes proyectos que impliquen a varios
programadores.
Es la mejor herramienta para problemas en los que haya que
trabajar con texto el 90% del tiempo y un 10% en el resto.
En su día era el motor de las webs dinámicas (que se
ajustan a la perfección al caso anterior)
6. ¿Cuándo no usarlo?
Si el software a distribuir no se puede
distribuir con código fuente:
No se pueden generar binarios.
Si no quieres que tus colegas te miren raro...
7. Nuestro primer programa
Abrimos nuestro editor de texto/IDE y escribimos
1.#!/usr/bin/perl
2.print "Mi primer programan";
Línea 1: indica al intérprete qué ejecutable usar para
interpretar el programa
Línea 2: imprime por pantalla
8. Ejecutando el programa
A través de nuestro IDE, si lo soporta
Usando la línea de comandos:
perl miscript.pl
chmod +x miscript.pl
./miscript.pl
Esta forma sólo funciona si el script
contiene la línea #!/usr/bin/perl
9. ...y ahora lo escribimos en
perl
1.#!/usr/bin/perl
2.use 5.010;
3.say "Hello World!";
línea 2: forzamos el uso de una versión determinada
de perl (5.10)
línea 3: usamos la función “say” (disponible en 5.10)
porque es más concisa (escribimos menos)
10. Un script que hace “algo”
1.#!/usr/bin/perl
2.@lines = `perldoc -u -f atan2`;
3.foreach (@lines) {
4. s/w<([^>]+)>/U$1/g;
5. print;
6.}
...no te preocupes si no lo entiendes
¡para eso estamos aquí!
14. Escalares
Tipo de dato más simple que podemos encontrar
en perl
Sirve para almacenar “una unidad algo”
15. Escalares
Tipo de dato más simple que podemos encontrar
en perl
Sirve para almacenar “una unidad algo”
La mayoría de escalares son números o cadenas
de caracteres.
16. Escalares
Tipo de dato más simple que podemos encontrar
en perl
Sirve para almacenar “una unidad algo”
La mayoría de escalares son números o cadenas
de caracteres.
Sí, en perl no hay mucha diferencia entre una
cadena y un número y el intérprete puede usarlos
indistintamente en casi todos los contextos.
19. Escalares: números
Definición de literal: cómo se representa un
valor en el código fuente de perl.
Perl almacena los números internamente
siempre como “double”, no existe el entero
internamente en perl.
22. Acordarse más adelante
de decir porqué no
Escalares: números
podemos usar la coma
para separar grupos de
números.
Literales de entero
0
2011
-40
8_817_264_612_412
Así es más claro. Más adelante veremos
porqué no podemos usar la coma
28. Tal y como dice el libro,
podríamos coger un
Escalares: cadenas
binario, meterlo en un
escalar como una cadena
de texto, modificarlo y
guardarlo a disco.
¿Tenemos un ejemplo de
esto en algún lado?
Una cadena es una secuencia de caracteres, por
ejemplo:
hola
☃★๛
Cadena más corta: cadena vacía
Cadena más larga: la que soporte nuestra
memoria ¡no hay límite a nivel del intérprete!
29. Escalares: cadenas
Perl soporta unicode.
No activo por defecto por compatibilidad con
scripts más antiguos.
Para activarlo, utilizar el siguiente pragma al
inicio de nuestros scripts:
use utf8
El fichero tiene que almacenarse en utf8/unicode
30. Escalares: cadenas
Literales de cadena en perl usando comillas simples:
‘hola’
‘’ -> cadena vacía
‘Cadena con dos ‘apostrofos’ dentro’
‘Cadena con una barra invertida’
‘Cadena con un
retorno de carro’ (contiene 30
caracteres)
31. Escalares: cadenas
Literales de cadena en perl usando comillas dobles:
“hola”
“” -> cadena vacía
“Cadena con dos ”comillas” dentro”
“Cadena con ‘comillas simples’ dentro“
Las comillas dobles expanden los caracteres de escape:
“holata todos” ->tabulador
“hola a todosn”
“x{2668}”
33. Escalares: cadenas
n Newline
r Return
t Tab
f Formfeed
b Backspace
a Bell
e Escape (ASCII escape character)
007 Any octal ASCII value (here, 007 =
bell)
x7f Any hex ASCII value (here, 7f =
delete)
x{2744} Any hex Unicode code point
(here, U+2744 = snowflake)
34. Escalares: cadenas
n Newline cC A “control” character (here, Ctrl-C)
r Return Barra invertida
t Tab “ Comilla doble
f Formfeed l Siguiente letra en minúscula
b Backspace L Todas las siguientes letras en minúscula
a Bell
hasta que se encuentre E
e Escape (ASCII escape character) u Siguiente letra en mayúscula
007 Any octal ASCII value (here, 007 = U Todas las siguientes letras en mayúscula
bell) hasta que se encuentre E
x7f Any hex ASCII value (here, 7f = Q Escapa todo lo que no sea una letra
delete) añadiendo una barra invertida hasta que se
encuentre E
x{2744} Any hex Unicode code point
(here, U+2744 = snowflake) E Finaliza L, U, or Q
35. Escalares: cadenas
Las comillas dobles interpolan variables
1.#!/usr/bin/perl
2.use 5.010;
3.use utf8;
4.$saludo = 'Hola';
5.say "$saludo a todos";
------
Salida: Hola a todos
37. Escalares: operadores de
cadenas
Concatenación: · (punto)
“hola” . ‘ a todos’
“hola a todos” . “n”
38. Escalares: operadores de
cadenas
Concatenación: · (punto)
“hola” . ‘ a todos’
“hola a todos” . “n”
Repetición de cadena
“Cadena”x3 -> devuelve CadenaCadenaCadena
39. Escalares: operadores de
cadenas
Concatenación: · (punto)
“hola” . ‘ a todos’
“hola a todos” . “n”
Repetición de cadena
“Cadena”x3 -> devuelve CadenaCadenaCadena
¿Qué devuelve lo siguiente?
5x4.8
40. Escalares: operadores de
cadenas
Concatenación: · (punto)
“hola” . ‘ a todos’
“hola a todos” . “n”
Repetición de cadena
“Cadena”x3 -> devuelve CadenaCadenaCadena
¿Qué devuelve lo siguiente?
5x4.8 -> 5555
41. Escalares: conversión
automática de tipos
¿porqué 5x4.8 devuelve 5555?
Para perl no hay mucha diferencia entre 5 y “5” a la hora de
almacenar. La distinción se hace a la hora de “usar” el literal.
x es un operador de cadena, y espera dos argumentos:
una cadena a la izquierda
un entero a la derecha
por lo tanto, convertirá el primer operando a una cadena y el
segundo a un entero
lo hace el sólo, nosotros no tenemos que preocuparnos de
hacer la conversión de tipos
43. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”;
say “5” + 24;
say 7 . 34;
say 7.34;
say “hola” * 3;
say 6 * “12 es docena”;
say “1.67” * “100”;
say ‘0xF’ * 10;
44. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”; 36
say “5” + 24; 29
say 7 . 34;
say 7.34;
say “hola” * 3;
say 6 * “12 es docena”;
say “1.67” * “100”;
say ‘0xF’ * 10;
45. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”; 36
say “5” + 24; 29
say 7 . 34; 734
say 7.34;
say “hola” * 3;
say 6 * “12 es docena”;
say “1.67” * “100”;
say ‘0xF’ * 10;
46. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”; 36
say “5” + 24; 29
say 7 . 34; 734
say 7.34; 7.34
say “hola” * 3;
say 6 * “12 es docena”;
say “1.67” * “100”;
say ‘0xF’ * 10;
47. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”; 36
say “5” + 24; 29
say 7 . 34; 734
say 7.34; 7.34
say “hola” * 3; 0 (número)
say 6 * “12 es docena”;
say “1.67” * “100”;
say ‘0xF’ * 10;
48. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”; 36
say “5” + 24; 29
say 7 . 34; 734
say 7.34; 7.34
say “hola” * 3; 0 (número)
say 6 * “12 es docena”; 72
say “1.67” * “100”;
say ‘0xF’ * 10;
49. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”; 36
say “5” + 24; 29
say 7 . 34; 734
say 7.34; 7.34
say “hola” * 3; 0 (número)
say 6 * “12 es docena”; 72
say “1.67” * “100”; 167
say ‘0xF’ * 10;
50. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”; 36
say “5” + 24; 29
say 7 . 34; 734
say 7.34; 7.34
say “hola” * 3; 0 (número)
say 6 * “12 es docena”; 72
say “1.67” * “100”; 167
say ‘0xF’ * 10; 0 (número)
51. Escalares: conversión
automática de tipos
un pequeño test:
say “12” * “3”; 36
say “5” + 24; 29
say 7 . 34; 734
say 7.34; 7.34
say “hola” * 3; 0 (número)
say 6 * “12 es docena”; 72
say “1.67” * “100”; 167
say ‘0xF’ * 10; 0 (número)
52. Escalares: warnings
Se pueden activar de dos maneras:
use warnings; (sólo a partir de 5.6)
#!/usr/bin/perl -w
perl -w script.pl
La primera tiene la ventaja de que se activan
sólo para el fichero en la que usa el pragma.
Las otras dos se activan para todos los guiones.
53. Escalares: warnings
say “5” + 3; -> no genera un warning
say “5 manzanas” + 3 -> genera un
warning
Argument "5 manzanas" isn't numeric in addition
(+) at warnings.pl line 12 (#1)
54. Escalares: warnings
¿y si el warning no es suficiente?
use diagnostics
perl -Mdiagnostics script.pl
Argument "5 manzanas" isn't numeric in addition (+) at diagnostics.pl
line 12 (#1)
(W numeric) The indicated string was fed as an argument to an
operator that expected a numeric value instead. If you're
fortunate the message will identify which operator was so
unfortunate.
http://perldoc.perl.org/perldiag.html tiene toda la
documentación sobre los errores
61. Escalares: variables
Almacenan un escalar
Comienzan por $ seguido de un identificador:
$nombre
$_nombre
$apellido1
$nombre_y_apellidos_del_usuario
62. Escalares: variables
Almacenan un escalar
Comienzan por $ seguido de un identificador:
$nombre
$_nombre
$apellido1
$nombre_y_apellidos_del_usuario
$2nombres -> MAL
63. Escalares: variables
Almacenan un escalar
Comienzan por $ seguido de un identificador:
$nombre
$_nombre
$apellido1
$nombre_y_apellidos_del_usuario
$2nombres -> MAL
$años -> correcto si se utiliza use utf8;
65. Escalares: variables
Imprimiendo variables:
say $nombre
say “$nombre” -> se prefiere la primera ¡hay que
escribir menos!
say “$nombre nació en $año”;
$singular = “dedo”;
say “$singulars”; -> no funciona
say “${singular}s” ->este sí
66. Escalares: comparación
Operación Número Cadena
Igual == eq
Distinto != ne
Menor que < lt
Mayor que > gt
Menor o igual <= le
Mayor o igual >= ge
68. Escalares: if
1.if ($nombre gt 'luis') {
2. print "'$name' va después que 'luis'.n";
3.} else {
4. print "'$name' o va antes que luis 'fred'.n";
5. print "o es la misma cadenan";
6.}
69. Escalares: verdadero o
falso
Si el escalar es el número 0 es falso, cualquier
otro número es verdadero
Si el escalar es una cadena vacía, es falso,
cualquier otra cadena es verdadero
Si no es un número o una cadena, convertirlo a
cadena o número y volver a intentarlo
Nota: la única cadena que se convierte a falso,
además de la cadena vacía es ‘0’
70. Escalares: entrada
Para leer la entrada estándar usamos el
operador <STDIN>
Se puede usar en cualquier lugar en el que perl
espere un escalar.
Perl sustituirá el operador <STDIN> por la
entrada estándar
$linea = <STDIN>
71. Escalares: chomp
Toma una cadena como argumento y elimina el
retorno de carro (n)
1.$text = "a line of textn";
2.chomp($text);
72. Escalares: while
1.$contador = 0;
2.while ($contador < 10) {
3. $contador += 2;
4. print "Contador vale $contadorn";# devuelve 2 4 6 8 10
5.}
El cuerpo del bucle se evalúa cuando la condición
es verdadera
73. Escalares: until
1.$contador = 0;
2.untill ($contador == 10) {
3. $contador += 2;
4. print "Contador vale $contadorn";# devuelve 2 4 6 8 10
5.}
El cuerpo del bucle se evalúa cuando la condición
es falsa
74. Ejercicios
1. Escribe un programa que calcule el perímetro de una circunferencia de radio 12.5. El
perímetro es 2π veces el radio (π = 3.141592654). La respuesta debe estar entorno a
78.5.
2. Modificar el programa anterior para que el usuario pueda introducir el radio de la
circunferencia.
3. Modificar el programa anterior de forma que, si el usuario introduce un número
negativo, el perímetro sea cero.
4. Escribe un programa que lee dos números (en dos líneas de texto separadas) y calcula
el producto.
5. Escribe un programa que lea una cadena y un número y muestre la cadena repetida en
tantas líneas como el número que haya introducido el usuario. Si se introduce Luis y 3
se devolverán tres líneas en las que pone “Luis”. Si se introduce “Luis” y 789979 saldrán
muchas líneas
Notas del editor
\n
\n
\n
Referencia: learning perl 6th ed. p&#xE1;gina 6\nDise&#xF1;ado de la siguiente manera: a veces Larry ten&#xED;a que elegir entre estas dos opciones:\n- hacerlo f&#xE1;cil para el estudiante/novato\n- hacerlo m&#xE1;s dif&#xED;cil de aprender pero m&#xE1;s f&#xE1;cil para el programador experimentado.\n\n...se escogi&#xF3; siempre la segunda opci&#xF3;n.\n\nEjemplo de c&#xF3;digo:\n- Utiliza funciones con par&#xE1;metros por defecto\n- syntaxis compacta\n- si no se usasen estas caracter&#xED;sticas de perl el mismo c&#xF3;digo ocupar&#xED;a mucho m&#xE1;s\n\n
\n
\n
\n
\n
Referencia: learning perl 6th ed. p&#xE1;gina 13-14\n\nLo haremos durante todo el curso: buscaremos siempre la manera de usar la sintaxis compacta de perl.\n\nla versi&#xF3;n menor son tres d&#xED;gitos, es decir use 5.010 se convierte en 5.10. Si ponemos use 5.100 esto se expande a la versi&#xF3;n 5.100 que no existe (existe la 5.10).\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
\n
Learning Perl 6th ed. p&#xE1;gina 24\n\nDado que en perl podemos tener cualquier caracter en una cadena, podr&#xED;amos hacer lo siguiente:\n- Leer un fichero binario (una imagen por ejemplo) en un escalar.\n- Modificarlo\n- Volver a guardarlo al disco.\n
\n
\n
\n
ejemplo: secuencias_escape.pl\n
ejemplo: secuencias_escape.pl\n
\n
ejemplo: operadores_cadena.pl\n
ejemplo: operadores_cadena.pl\n
ejemplo: operadores_cadena.pl\n
operadores_cadena.pl\n
\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Comentario: para que el &#xFA;ltimo funcione es necesario hacer \n\nsay hex(&#x2018;xF&#x2019;) * 10;\nsay oct(&#x2018;032&#x2019;) * 10;\n\nEjemplo: conversion_tipos.pl\n
Como hemos visto y veremos, el int&#xE9;rprete puede hacer muchas cosas por nosotros en funci&#xF3;n del contexto.\n&#xBF;C&#xF3;mo hacemos para que nos avise cuando ve algo sospechoso?\n
\n
Mostrar el ejemplo de warnings: warnings.pl\n
learning perl 6th edition p&#xE1;gina 30\nejemplo: variables.pl \n\nNombres de variables:\n$a -> no es muy descriptivo\n\nprint &#x201C;$a $b $r -> $j&#x201D;;\nprint &#x201C;$nombre $apellido1 $apellido2 -> $a&#xF1;o&#x201D;; es mucho m&#xE1;s claro\n
learning perl 6th edition p&#xE1;gina 30\nejemplo: variables.pl \n\nNombres de variables:\n$a -> no es muy descriptivo\n\nprint &#x201C;$a $b $r -> $j&#x201D;;\nprint &#x201C;$nombre $apellido1 $apellido2 -> $a&#xF1;o&#x201D;; es mucho m&#xE1;s claro\n
learning perl 6th edition p&#xE1;gina 30\nejemplo: variables.pl \n\nNombres de variables:\n$a -> no es muy descriptivo\n\nprint &#x201C;$a $b $r -> $j&#x201D;;\nprint &#x201C;$nombre $apellido1 $apellido2 -> $a&#xF1;o&#x201D;; es mucho m&#xE1;s claro\n
learning perl 6th edition p&#xE1;gina 30\nejemplo: variables.pl \n\nNombres de variables:\n$a -> no es muy descriptivo\n\nprint &#x201C;$a $b $r -> $j&#x201D;;\nprint &#x201C;$nombre $apellido1 $apellido2 -> $a&#xF1;o&#x201D;; es mucho m&#xE1;s claro\n
learning perl 6th edition p&#xE1;gina 30\nejemplo: variables.pl \n\nNombres de variables:\n$a -> no es muy descriptivo\n\nprint &#x201C;$a $b $r -> $j&#x201D;;\nprint &#x201C;$nombre $apellido1 $apellido2 -> $a&#xF1;o&#x201D;; es mucho m&#xE1;s claro\n
learning perl 6th edition p&#xE1;gina 30\nejemplo: variables.pl \n\nNombres de variables:\n$a -> no es muy descriptivo\n\nprint &#x201C;$a $b $r -> $j&#x201D;;\nprint &#x201C;$nombre $apellido1 $apellido2 -> $a&#xF1;o&#x201D;; es mucho m&#xE1;s claro\n
learning perl 6th edition p&#xE1;gina 30\nejemplo: variables.pl \n\nNombres de variables:\n$a -> no es muy descriptivo\n\nprint &#x201C;$a $b $r -> $j&#x201D;;\nprint &#x201C;$nombre $apellido1 $apellido2 -> $a&#xF1;o&#x201D;; es mucho m&#xE1;s claro\n
learning perl 6th edition p&#xE1;gina 30\nejemplo: variables.pl \n\nNombres de variables:\n$a -> no es muy descriptivo\n\nprint &#x201C;$a $b $r -> $j&#x201D;;\nprint &#x201C;$nombre $apellido1 $apellido2 -> $a&#xF1;o&#x201D;; es mucho m&#xE1;s claro\n
\n
Nombrar\n
\n
\n
La comparaci&#xF3;n admite cualquier escalar &#xBF;c&#xF3;mo decide perl si el escalar es verdadero o falso?\n
\n
Hacer el siguiente script de ejemplo:\n\nsay &#x201C;Di algo:&#x201D;;\n$line = <STDIN>;if ($line eq "\\n") {\nprint "That was just a blank line!\\n";\n } else {\n print "That line of input was: $line";\n}\n\n#<STDIN> se puede usar en cualquier lugar en el que perl espere un escalar\n# por lo que podemos usarlo directamente dentro del if\nsay "Di algo otra vez:";\nif (<STDIN> eq "\\n") {\n print "&#xA1;No has dicho nada!\\n";\n} else {\n print "&#xA1;O&#xED;do cocina!\\n";\n}\n\nVer c&#xF3;mo estamos comparando que el usuario no introduce nada. Esto lo podemos mejorar\n
Ejemplos a poner: chomp.pl\n# En este ejemplo usamos print para que no se imprima un \\n al final de cada l&#xED;nea en la consola\n$cadena = "Cadena con \\\\n al final\\n";\nprint $cadena;\n\nsay "Usamos la funci&#xF3;n chomp:";\nchomp $cadena;\n\nchomp2.pl\n\nsay "Di algo:"\nchomp ($line = <STDIN>);\nunless ($line) {\nprint "&#xA1;No has dicho nada!\\n";\n} else {\nprint "&#xBF;te he entendido bien?: $line\\n";\n}\nMacBo\n\n
\n
Ejercicio a hacer: pasarlo a una sola l&#xED;nea:\n\n$contador = 0;\nsay "contador vale ".($contador+=2) until $contador == 10;\n$contador = 0;\nsay "contador vale ".($contador+=2) while $contador < 10;\n