[Remembranza] Perl


Perl es un lenguaje de programación que ofrece amplias faciliades para el procesamiento de texto, aunque al ser derivado de C ofrece todas las características de propósito general deseables de un lenguaje. Por el momento, en Windows, ando usando ActivePerl. Pero entremos a lo importante... ¿cómo se usa?

Variables y Operadores

Son básicamente 3 tipos de variables: escalares, arreglos, y arreglos asociativos (parejas de claves y valores, hash) que se definen de la siguiente forma:

Asi pues, el uso sera:
Y no necesitan ser declaradas en ninguna parte del texto. Cada línea debe terminar con un ';'.

Entre los operadores se encuentran:

 + - * /Operadores matemáticos estándar
 =Asignación 
 ^Potencia 
 %Módulo 
 .Concatenación 
 XOperador repetición
 >>Salida a archivo (sobreescribe)
 >Salida a archivo (escribe al final)

Los operadores lógicos son:

 > Mayor que
 >= Mayor o igual que
 <= Menor o igual que
 < Menor que
 == Igual a
 != Diferente a
 && Y lógico
 || O lógico
 ! NO lógico

Perl tiene un conjunto de variables por default, las cuales son consultadas en el momento que damos alguna orden sin especificar una variable. Por ejemplo al poner:

Le estamos diciendo a Perl que busque una variable especial y la imprima, sin saber exactamente que tenemos dentro de ella. La variable es llamada $_, sus usos son variados, por ejemplo, al invocar una subrutina, los parámetros son guardados en @_, y se pueden acceder por medio de $_[indice].

Arreglos y Hashes


Al aprecer Perl ofrece unas excelentes propiedades para el trabajo sobre arreglos de elementos:

En este caso, se debe citar que la indización en Perl comienza desde 0, asi mismo se puede definir exhaustivamente elemento por elemento (@arreglo[$i] = 'loquesea';), cabe señalar un hash es un tipo de array donde los índices tienen nombres particulares y se accesan con esos nombres (y corchetes {}):

Si deseamos conocer la cantidad de elementos de un array solo necesitamos igualar nuestro array a una variable: $cantidad = @arreglo, así también podemos extraer los valores y las claves (índices) de un arreglo asociativo (o hash):

Y si queremos recorrelo podemos hacer:
 
Ahora bien, hasta el momento he tratado los arreglos como unidadees de un tamaño determinado (muy similares a los arreglos de C), sin embargo los arreglos de Perl son más bien como pilas y colas, y son susceptibles de accesarse de esa misma forma mediante un conjunto de funciones:

Push

Esta función agrega un elemento a un array justo al final (como una cola):

La cual agregará un elemento y nuestro @arreglo ahora tendrá 3 y el último será el que acabamos de agregar.

Pop

Es el contrario de push, retira un elemento del final del arreglo:

Lo cual dejará nuestro @arreglo de la misma forma que en su definición.

Shift

Esta función retira un elemento del comienzo del arreglo, funciona como una pila:

Dejando nuestro arreglo con solo el segundo elemento.

Unshift

Es la función opuesta a shift, que agrega elementos al principio de un arreglo.


Grep

Grep busca un valor específico dado el arreglo y la expresión (patrón) a buscar:

En este casos e busca el patron "ex" en el arreglo, como no existe esa cadena en ninguno de los elementos, la busqueda continua vacia.

Slice

Si desea retirar una porción del arreglo (no borrarla, consultarla), se usa un operador de acceso al arrelgo, más que una función es una forma de acceder a los datos:

Si los índices son negativos, le estamos diciendo a Perl que cuente en el arrelgo de atras para adelante.

Splice

Esta función retira del arreglo (esta si los borra) un conjunto de valores en un intervalo específico y los reemplaza por otro conjunto de valores:

En este caso le decimos que haga un splice en @arreglo desde $inicio y por una cantidad $tamaño de elementos, los cuales reemplazará por los elementos citados desde "valoresN".

Reverse

Esta función cambia el orden del areglo, lo invierte:

Sort

Esta lo que hace es ordenar los elementos del arreglo de mayor a menor (si son numéricos, o en orden alfabético (en caso de ser cadenas de caracteres).

Split

Esta función separa una cadena de caracteres mediante algun delimitador (que nosotros definimos) y agrega los elementos resultantes a un arreglo:

Donde la $cadena se separa donde se encuentre la expresión "ex", en este caso, no hay ninguna separación, lo mejor hubiese sido usar '/ /'.

Join

Es la versión "opuesta" de split, lo que hace es tomar los elementos de un arreglo y unirlos en una cadena de caracteres con un caracter de unión definido:
 
Por otra parte, los arreglos asociativos ofrecen un conjunto de funciones para su alteración, que corresponden a las de los arreglos (aunque en mi concepto son más poderosas). esto dado que Perl no organiza los elementos del hash de la misma manera en que son definidos, como pasa en un arreglo, sino optimiza su organización, por consiguiente no tiene sentido intentar hacer un push o un unshift:

Delete

Esta función borra un elemento dada una clave:

Exist

Esta función detemrina si una clave específica pertenece al hash y retorna un booleano como respuesta:
 

Matrices

En perl no se soportan nativamente variables complejas (como matrices) pero se pueden hacer a parte de combinación de arreglos, variables comunes y arreglos asociativos. Para definir una matriz  se usa un arreglo de arreglos:

En este caso los arreglos internos son anónimos (no tienen un nombre) y son, de manera precisa,  referencias (aputadores) a otras listas. La forma para acceder a los elementos sigue la misma notación convencional de un arrelo multidimensional en C.

Así mismo puede usarse un hash de hashes:

El cual será accesado como:

Si las claves tiene como nombre el conjunto numèrico (0,1,2...) el hash se vería como una matriz:


Estructuras de Control

Las estructuras básicas de control son:


Subrutinas

Para definir una subrutina se usa la palabra reservada 'sub', a diferencia de  muchos lenuajes no debemos especificar sus parámetros, pero entonces debemos tener especial cuiado al momento de invocar las funciones.

En este caso definimos una rutina, donde se multiplican 2 parámetros y se retornan, aca cabe introducir el operador 'my', el cual define a '$variable' como privada a la rutina, por consiguiente no puede ser accesada directamente desde ningún otra parte del programa. Dado esto la llamada debería ser:

Así pues cada parámetro queda almacenado en un elemento de @_, como se observa podemos hacer el llamado a la función usando el operador '&', sin embargo esto no es estrictamente necesario, si nos aseguramos que las funciones esten definidas antes de ser invocadas, y no comparten nombre con ninguna de las funciones propias de Perl no habrá ningun porblema con hacer el llamado sin ese operador.

I/O

Perl recibe tambien datos desde la consola como cualquier lenguaje, de lo contrario seria uno muy malo. Por default la salida estándar es la pantalla y la entrada estándar es el teclado a menos que se especifique algo diferente (como un archivo).

Para recibir un dato del teclado usamos el operador '', de la siguiente forma:

Perl se detendrá de la lectura cuando se introduzca el caracter de EoF (no un enter como en otros lenguajes).

De la misma manera para imprimir en la salida estándar se usara el comando 'print'

En ocasiones deseamos leer una lista de parámetros desde la invocación del programa, para eso usamos el operador '<>', denominado operador diamante, el cual captura todos los parámetros enviados junto con la invocación del programa, los cuales son almacenados en el operador especial $_.

En este caso le decimos que mientras haya contenido en la invocación, lo imprima. Por ejemplo, si le adjuntamos un texto, imprimirá el contenido del texto.

Así mismo, podemos acceder individualmente a cada parámetro por medio del arreglo @ARGV, el cual almacena cada unno de los parámetros en un elemento del arreglo, si la llamada es:

Obtendremos lo siguiente:

Las cuales son todas accesibles desde el código del programa.

Formato de salida

Todas las cadenas de salida son susceptibles a ser formateadas con algún tipo de dato específico de la siguiente manera:

 %sString
 %gUn número sin importar el tipo (es automático)
 %dEnteros truncado
 %fPunto flotante 

Pero para hacer uso de esto se debe usar la función de salida 'printf' cuyos parámetros son el formato y el valor a imprimir:

De la misma manera se le puede agregar un formato adicional, de modo que muestre los resultados de una u otra forma, así:

Archivos

Para trabajar con archivos los operadores son:

Bytes es la cantidad de bytes a desplazarse y posición es el lugar desde donde se inicia el desplazamiento, puede ser: SEEK_SET (inicio), SEEK_CUR (actual) y SEEK_END (el final).

Donde variable va a ser el contenedor y bytes la cantidad a leer.


Empaquetado

En ocasiones la escritura o lectura de un archivo debe hacerse en binario, y es necesario, por ejemplo, leer datos combinados hexadecimales, caracter, decimal, etc..., asi pues:

En este caso, se desempaca en 'var#' lo que esta en 'variable', y luego se empaca en 'variable' lo que esta en 'var#'. El modo es el conjunto de reglas para realizar el proceso, que se pueden consultar aca. Ejemplo:

La cual desempaca 2 caracteres, un string ASCII de 10 letras y un Hexadecimal de 3 caracteres.

POOP

De la misma forma que otros lenguajes de programación, Perl posee ciertas condiciones que facilitan la orientación a Objetos, pero no son idénticas a los de lenguajes como C++ o Java, más bien tienen una estructura peculiar. En primera instancia, para crear una clase en Perl debemos definir un paquete:

Cada paquete es un conjunto de rutinas y variables empaquetadas que pueden ser usadas varias veces.Dentro de nuestro paquete (la clase 'clase') es necesario definir el que será el constructor para los objetos, en Perl habitualmente se usa el nombre 'new' para la subrutina constructora, pero puede ser cualquiera, asi pues:

La cual es una subrutina en donde se definen los atributos locales (por eso el 'my') mediante un hash de referencias, y se inicializan como indefinidas ('undef'), el underscore, considero, es fashion. El 'bless' le indica  a Perl que desde ahora esa referencia del constructor es una instancia de el objeto '$class', es un llamado habitual despues de los constructores de las clases. La primera línea facilita la herencia de la clase definiendo el nombre a partir de un array de argumentos '@_'(que en este caso, contendrá el nombre de la clase al crear el objeto). Así mismo, dentro del mismo paquete se pueden construir todas las funciones que necesitemos, en particular las funciones para accesar y para modificar los atributos de nuestros objetos:

Una subrutina donde se recibe el objeto y el atributo para ser modificado dentro de la instancia de nuestra clase.

Luego, para crear un objeto de nuestra clase y accesarlo:


Apuntadores

En ocasiones para llevar un control de datos y crear variables de manera dinámica es necesario el uso de apuntadores, en Perl es un proceso muy facil, dado que no es necesario definir los datos de algun tipo específico dentro del código, sino que estos se ajustan dinámicamente al contenido. Un apuntador guarda la dirección en memoria de una variable, y la manera para encontrar esa drección es a través del operador '\':

VariableApuntador 
 $escalar \$escalar
 @array \@array 
 %hash \%hash 
 función \&funcion

Así pues, para crear un apuntador a una variable específica solo debemos:

Donde se crea un arreglo con la función 'Quote Word' y un hash pequeño, y luego con 2 apuntadores se encuentra la dirección en memoria de cada una de nuestras variables.

Para accesar las variables a partir de los apuntadores solo se debe usar el operador '->' o una construcción '$$' (para escalares, por ejemplo), asi:

Así pues, se puede accesar como si fuese un arreglo a partir del apuntador, o directamente desde el apuntador usando el operador doble, el concepto es simple: $apuntador->[2] accesa el elemento 2 del '@arreglo', al cual apuntamos con '$apuntador', para accesar el mismo elemento se usaria $arreglo[2], luego, compactando ambas expresiones, podriamos escribir $$apuntador[2], de forma tal que le decimos a Perl que en la dirección de apuntador hay un valor escalar que corresponde a la segunda posicion del arreglo.

En ocasiones necesitamos tener variables creadas en memoria, pero no queremos nombrarlas (como por ejemplo para una lista enlazada), para eso Perl permite la creacion de apuntadores a variables sin nombre (anónimas les dicen), de la siguiente forma:

Y accesarlos como se haría normalmente:

Referencias


Entradas más populares de este blog

Proteger entradas en Blogger

Poema Árabe bellísimo

Y llegó Ubuntu 9.10 Karmic Koala