Perl es un lenguaje de programación diseñado por Larry Wall en 1987. Perl toma características del lenguaje C, del lenguaje interpretado bourne shell (sh), AWK, sed, Lisp y, en un grado inferior, de muchos otros lenguajes de programación.
Estructuralmente, Perl está basado en un estilo de bloques como los del C o AWK, y fue ampliamente adoptado por su destreza en el procesado de texto y no tener ninguna de las limitaciones de los otros lenguajes de script.
CARACTERISTICAS:
La estructura completa de Perl deriva ampliamente del lenguaje C. Perl es un lenguaje imperativo, con variables, expresiones, asignaciones, bloques de código delimitados porllaves, estructuras de control y subrutinas.
Perl también toma características de la programación shell. Todas las variables son marcadas con un Sigilo precedente (Sigil, en inglés). Los sigilos identifican inequívocamente los nombres de las variables, permitiendo a Perl tener una rica sintaxis. Notablemente, los sigilos permiten interpolar variables directamente dentro de las cadenas de caracteres(string). Como en los shell, Perl tiene muchas funciones integradas para tareas comunes y para acceder a los recursos del sistema.
Perl toma las listas del Lisp, hash (memoria asociativa) del AWK y expresiones regulares del sed. Todo esto simplifica y facilita todas las formas del análisis sintáctico, manejo de texto y tareas de gestión de datos.
En Perl 5, se añadieron características para soportar estructuras de datos complejas, funciones de primer orden (p. e. clausuras como valores) y un modelo de programación orientada a objetos. Éstos incluyen referencias, paquetes y una ejecución de métodos basada en clases y la introducción de variables de ámbito léxico, que hizo más fácil escribir código robusto (junto con el pragma strict). Una característica principal introducida en Perl 5 fue la habilidad de empaquetar código reutilizable como módulos. Larry Wall indicó más adelante que "la intención del sistema de módulos de Perl 5 era apoyar el crecimiento de la cultura Perl en vez del núcleo de Perl".5
Todas las versiones de Perl hacen el tipificado automático de datos y la gestión de memoria. El intérprete conoce el tipo y requerimientos de almacenamiento de cada objeto en el programa; reserva y libera espacio para ellos según sea necesario. Las conversiones legales de tipo se hacen de forma automática en tiempo de ejecución; las conversiones ilegales son consideradas errores fatales.
Tipos de datos
Perl tiene tres tipos de datos: escalares, listas y hashes:
- Un escalar es un solo valor; puede ser un número, un string (cadena de caracteres) o una referencia
- Una lista es una colección ordenada de escalares (una variable que almacena una lista se llama array)
- Un hash, o memoria asociativa, es un mapeo de strings a escalares; los strings se llaman claves y los escalares valores.
Todas las variables están precedidas por un sigilo, que identifica el tipo de dato que es accedido (no el tipo de dato de la misma variable). Se puede usar el mismo nombre para variables de diferentes tipos, sin que tengan conflictos.
$var # un escalar @var # un array %var # un hash Los números se escriben de la forma usual; los strings están rodeados entre comillas de varias clases.
$n = 42; $nombre = "juan"; $color = 'rojo'; Perl convertirá los strings en números y viceversa dependiendo del contexto en que sean usados. En el siguiente ejemplo los strings $n y $m son tratados como números cuando son argumentos del operador suma. Este código imprime el número '5', desechando cualquier información no numérica de la operación y dejando los valores de las variables intactos. (El operador de concatenación no es +, sino ..)
$n = "3 manzanas"; $m = "2 naranjas"; print $n + $m; Perl también tiene un contexto booleano que utiliza en la evaluación de declaraciones condicionales. Los siguientes valores en Perl evalúan todos como falso:
$falso = 0; # el número cero $falso = 0.0; # el número cero como flotante $falso = '0'; # el string cero $falso = ""; # el string vacío $falso = undef; # el valor devuelto por undef Todos los demás valores se evalúan a verdadero. Esto incluye el curioso string auto-descriptivo "0 pero verdadero", que de hecho es 0 como número, pero verdadero como booleano. (Cualquier string no numérico también tendrá esta propiedad, pero este string en particular es ignorado por Perl en contextos numéricos). Las expresiones booleanas evaluadas también devuelven valores escalares. Aunque la documentación no indica qué valor particular se devuelve como verdadero o falso (y por lo tanto no fiable), muchos operadores booleanos devuelven 1 por verdadero y el string vacío para falso (que evalúa a cero en contexto numérico). La función defined() le dice si la variable tiene algún valor. En el ejemplo anterior defined($falso) será verdadero con cada uno de los valores anteriores, excepto undef. Si, específicamente, quiere asegurarse de tener un resultado 1/0 (como en C), necesita realizar el cálculo siguiente:
my $resultado_real = $resultado_booleano ? 1 : 0; Una lista se define listando sus elementos, separados por comas y rodeados por paréntesis donde así sea requerido por la precedencia de los operadores.
@puntuaciones = (32, 45, 16, 5); Un hash puede ser inicializado desde una lista de pares clave/valor.
%favorito = ( joe => 'rojo', sam => 'azul', ); Los elementos individuales de una lista son accedidos utilizando un índice numérico, dentro de corchetes. Valores individuales en un hash son accedidos utilizando la correspondiente clave, dentro de llaves. El sigilo $ identifica que el elemento accedido es un escalar.
$puntuaciones[2] # un elemento de @puntuaciones $favorito{joe} # un valor de %favorito Múltiples elementos pueden ser accedidos usando en su lugar el sigilo @ (identificando el resultado como una lista).
@puntuaciones[2, 3, 1] # tres elementos de @puntuaciones @favorito{'joe', 'sam'} # dos valores de %favorito El número de elementos en un array puede ser obtenido evaluando el array en contexto escalar o con la ayuda del sigilo $#. Éste último da el índice del último elemento dentro del array, no el número de elementos.
$numero = @amigos; $#amigos; # el índice del último elemento en @amigos $#amigos+1; # normalmente el número de elementos en @amigos, # que es uno más que $#amigos porque el primer elemento tiene el índice 0, no 1 Hay unas pocas funciones que operan sobre hashes enteros.
@nombres_de_clientes = keys %direcciones; # guarda en @nombres_de_clientes todas las claves de %direcciones @direcciones_de_email = values %direcciones; # guarda en @direcciones_de_email todos los valores de %direcciones Estructuras de control
Perl tiene varias clases de estructuras de control.
Tiene estructuras de control orientado al bloque, similar a los de los lenguajes de programación C y Java. Las condiciones están rodeadas por paréntesis y los bloques subordinados por llaves:
''etiqueta'' while ( ''condición'' ) {... } ''etiqueta'' while ( ''condición'' ) {... } continue {... } ''etiqueta'' for ( ''expresión inicial''; ''expresión condicional''; ''expresión incremental'' ) {... } ''etiqueta'' foreach ''var'' ( ''lista'' ) {... } ''etiqueta'' foreach ''var'' ( ''lista'' ) {... } continue {... } if ( ''condición'' ) {... } if ( ''condición'' ) {... } else {... } if ( ''condición'' ) {... } elsif ( ''condición'' ) {... } else {... } Cuando se controla a una sola declaración, los modificadores de declaración proporcionan una sintaxis más ligera:
''declaración'' if ''condición''; ''declaración'' unless ''condición''; ''declaración'' while ''condición''; ''declaración'' until ''condición''; ''declaración'' foreach ''lista''; Los operadores lógicos cortocircuito son normalmente usados para controlar el flujo del programa a nivel de expresión:
''expr'' and ''expr'' ''expr'' or ''expr'' Las palabras clave de control de flujo next, last, return y redo son expresiones, por lo que pueden ser usadas con los operadores cortocircuito.
Perl también tiene dos construcciones implícitas para bucles:
''resultados'' = grep {... } ''lista'' ''resultados'' = map {... } ''lista'' grep devuelve todos los elementos de lista en que el bloque subordinado evalúa a verdadero. map evalúa el bloque subordinado por cada elemento de lista y devuelve una lista de los valores resultantes. Estas construcciones permiten un estilo simple de programación funcional.
La declaración switch (llamada "given"/"when") existe desde la versión 5.10:
use 5.10.1; # o posterior given ($variable) { when (''condición'') { ... } when (''condición'') { ... } default { ... } } Perl incluye una declaración goto etiqueta, pero es usada raramente. Las situaciones donde en otros lenguajes se utiliza goto no ocurren tan a menudo en Perl debido a sus amplias opciones de control de flujo.
Existe también una declaración goto &sub que realiza una llamada 'final'. Termina la subrutina actual e inmediatamente llama a la sub especificada. Esto se usa en situaciones donde una nueva subrutina puede realizar una gestión de la pila más eficiente que el propio Perl (porque típicamente no se requiere ningún cambio en la pila actual), y en una recursión muy profunda este tipo de llamadas puede tener un sustancial impacto positivo en el funcionamiento porque evita la sobrecarga de la gestión contexto/pila en el momento de retornar.
Subrutinas
Las subrutinas se definen con la palabra clave sub e invocadas simplemente nombrándolas. Si la subrutina en cuestión no ha sido todavía declarada, es necesario, para el proceso de análisis sintáctico, poner los paréntesis.
foo(); # paréntesis necesarios aquí... sub foo {... } foo; #... pero no aquí Una lista de argumentos pueden ser indicados después del nombre de la subrutina. Los argumentos pueden ser escalares, listas o hashes.
foo $x, @y, %z; Los parámetros de una subrutina no necesitan ser declarados, ni en número ni en tipo; de hecho, pueden variar en cada llamada. Los arrays son expandidos a sus elementos, los hashes a una lista de pares clave/valor y todo el conjunto es pasado a la subrutina como una indiferenciada lista de escalares.
Cualesquiera de los argumentos pasados están disponibles para la subrutina en el array especial @_. Los elementos de @_ son asociados a los argumentos actuales; cambiando un elemento de @_ cambia el argumento correspondiente.
Los elementos de @_ pueden ser accedidos con los subíndices de la forma normal.
$_[0], $_[1] Sin embargo, el código resultante puede ser difícil de leer y los parámetros tener una semántica de pase por referencia, que puede resultar algo no deseable.
Un modismo común es asignar @_ a una lista de variables con nombres.
my($x, $y, $z) = @_; Esto afecta tanto a la mnemónica de los nombres de los parámetros como a la semántica de los valores pasados por valor. La palabra clave my indica que las siguientes variables están léxicamente embebidas en el bloque que las contienen.
Otro modismo es sacar los parámetros de @_. Esto es muy común cuando la subrutina toma un sólo argumento.
my $x = shift; # Si no se dice nada, nos referimos a @_ Las subrutinas pueden devolver valores.
return 42, $x, @y, %z; Si la subrutina no sale vía declaración return, entonces devuelve la última expresión evaluada en el cuerpo de la subrutina. Arrays y hashes en el valor de retorno son expandidos a una lista de escalares, igual que si fueran argumentos de una función.
La expresión devuelta es evaluada en el contexto de la llamada de la subrutina; esto puede sorprender al desprevenido.
sub lista { (4, 5, 6) } sub array { @x = (4, 5, 6); @x } $x = lista; # devuelve 6 - último elemento de la lista $x = array; # devuelve 3 - número de elementos de la lista @x = lista; # devuelve (4, 5, 6) @x = array; # devuelve (4, 5, 6) Una subrutina puede descubrir su contexto de llamada con la función wantarray.
sub cualquiera { wantarray ? (1, 2) : "Naranjas" } $x = cualquiera; # devuelve "Naranjas" @x = cualquiera; # devuelve (1, 2) Expresiones regulares con Perl, en inglésEl lenguaje Perl incluye una sintaxis especializada para escribir expresiones regulares y el intérprete contiene un motor para emparejar strings con expresiones regulares. El motor de expresiones regulares usa un algoritmo de Vuelta Atrás (backtracking), extendiendo sus capacidades desde el simple emparejamiento de patrones simples con la captura y sustitución de strings. El motor de expresiones regulares se deriva de regex, escrito por Henry Spencer.
La sintaxis de expresiones regulares fue originalmente tomada de las expresiones regulares de Unix Versión 8. Sin embargo, se diferenció ya antes del primer lanzamiento de Perl y desde entonces ha ido incorporando muchas más características. Otros lenguajes y aplicaciones están adoptando las expresiones regulares de Perl (PCRE) en vez de las expresiones regulares POSIX, incluyendo PHP, Ruby, Java y el Servidor HTTP Apache.
El operador m// (empareja) permite comprobar un emparejamiento por medio de una expresión regular. (Para abreviar, el precedente m puede ser omitido.) En el caso más simple, una expresión como:
$x =~ m/abc/ evalúa a verdadero si y sólo si el string $x empareja con la expresión regular abc.
Partes de la expresión regular pueden ser incluidas entre paréntesis: las partes correspondientes de un string emparejado son capturadas. Los strings capturados son asignados de forma secuencial a las variables internas $1, $2, $3,... y una lista de strings capturados se devuelve como valor del emparejamiento.
$x =~ m/a(.)c/; # captura el carácter entre 'a' y 'c' y lo guarda en $1 El operador s/// (sustitución) especifica una operación de búsqueda y reemplazo:
$x =~ s/abc/aBc/; # Convierte la b en mayúscula Las expresiones regulares en Perl pueden tomar unos modificadores. Son sufijos de una sola letra que modifican el significado de la expresión:
$x =~ m/abc/i; # emparejamiento independientemente de si están en mayúscula o minúscula $x =~ s/abc/aBc/g; # búsqueda y reemplazo global (a lo largo de todo el ''string'') Las expresiones regulares pueden ser densas y crípticas. Esto es porque la sintaxis de las expresiones regulares es extremadamente compacta, generalmente usando caracteres sueltos o pares de caracteres que representan sus operaciones. Perl alivia un poco este problema con el modificador /x que permite a los programadores poner espacio en blanco y comentarios dentro de las expresiones regulares:
$x =~ m/a # empareja una 'a' . # empareja cualquier carácter c # empareja una 'c' /x; Un uso común de las expresiones regulares es el de especificar delimitadores de campos al operador split:
@palabras = split m/,/, $línea; # divide la $línea de valores separados por comas El operador split complementa la captura de string. La captura de string devuelve las partes de un string que emparejan con una expresión regular; split devuelve las partes que no emparejan.