PERL

1- Introducción
1.1-PERL
1.1.1-¿Que es PERL?
1.1.2- Para que sirve
1.1.3- Donde puede usarse
1.1.4- Que fuentes de información existen
1.2- Filosofía de PERL
1.3- Diferencias entre PERL 4.3 y 5.X, Como elegir Versión

2- Programación Básica
2.1- Estructura Básica de un programa, programa Hola Mundo
2.2- Estructuras de datos básicas
2.2.1- Clases de Datos
2.2.1.1- Escalares
2.2.1.2- Arreglos
2.2.1.3- Hash o Arreglos asociativos
2.2.1.4- Equivalencias de Clases
2.2.3- Tipos especiales de Datos
2.2.3.1- Referencias
2.2.3.1.1- Creación
2.2.3.1.2- Uso
2.2.3.2- Archivos
2.2.3.2.1- Apertura
2.2.3.2.2- Uso y Cerrado
2.3- Operaciones Básicas
2.3.1- Aritméticas
2.3.2- Lógicas
2.3.4- Con Expresiones Regulares
2.3.5- Misceláneas
2.4- Estructuras de Control
2.4.1- Manejo de Subrutinas
2.5- Operaciones con Archivos
2.5.1- Apertura y Cerrado
2.5.2- Lectura de Datos
2.5.3- Escritura
2.5.4- Saltos y Proceso binario
2.6- Operaciones con Recursos del sistema
2.6.1- Como expresiones
2.6.2- Sin interrelaciones
2.6.3- Entubados

3- Programación Especial
3.1- Uso de Perl en línea, Tareas Comunes
3.1.1- Formas de Especificar el programa
3.1.2- Interruptores
3.1.3- Tareas Comunes de Perl en Línea de Comando
3.1.3.1- Reemplazar una cadena en un archivo por otra
3.1.3.2- Imprimir algún campo de un archivo
3.2- Programación de CGI, en Perl
3.2.1- cgi-lib.pl
3.2.2- CGI_Lite
3.3- Scripts para elaboración de reportes de texto
3.4- Expresiones Regulares
3.4.1- Símbolos Normales
3.4.1.1- Individuales
3.4.1.2- Genéricos
3.4.2- Símbolos Especiales
3.4.3- Uso de Expresiones regulares
3.4.3.1- Búsqueda
3.4.3.2- Substitución
3.4.4- Variables
3.4.4.1- Variables de entrada
3.4.4.2- Variables de salida

INTRODUCCION

arriba1.1- PERL

1.1.1- Que es PERL

Perl (Practical Extraction and Report Languaje) es un lenguaje deprogramación surgido a inicios de los noventas, que busca antes que nada el
facilitar la elaboración de tareas comunes en sistemas tipo UNIX, donde tradicionalmente las tareas de administración y proceso de datos se realiza con herramientas muy rudimentarias y por demás hostiles al usuario o administrador. Pero que se aplican sobre grandes cantidades de información (por lo regular texto) por lo que se requiere que sean de alto rendimiento.

Su autor, Larry Wall (lwall@netlabs.com) realizó Perl casi como una obra altruista, de modo que hasta PERL 5.X su distribución es gratuita, sin que por eso tenga menos poder o consistencia.

arriba1.1.2- Para que sirve

Perl surgió como una opción para una gran cantidad de herramientas de UNIX en las cuales basa su propia sintaxis, buscando el mínimo sacrificio de su desempeño por una máxima facilidad de programación e integración, sigue la filosofía de mantener un ambiente que sea capaz de detectar y corregir pequeñas omisiones del programador, y de proporcionarle una forma abreviada de realizar múltiples tareas. En una palabra, es una utilería que pretende facilitar el proceso de grandes volúmenes de información sin sacrificar el rendimiento.

arriba1.1.3- Donde Puede Usarse

Las plataformas donde Perl se ha desarrollado mas son los servidores UNIX, por sus necesidades de administración y lo robusto de su manejo de memoria y de procesos (requisitos de PERL hacia el S.O.) además de la facilidad de Perl para realizar los así llamados CGIs, interfaces para comunicar recursos del servidor con un servicio de internet particular (como podría ser WWW o gopher), En otras plataformas, PC en particular, se han desarrollado versiones que mantienen un razonable grado de funcionalidad, pero en realidad, el sistema DOS no tiene un manejo lo bastante bueno de los procesos o de la memoria para permitir a PERL dar un buen desempeño, además de que no es común ver en PC necesidades de administración de la magnitud de un servidor institucional. Sin embargo, puede practicarse la programación en PERL de PC, o incluso elaborar programas de reporteo en el , sin embargo, es algo que no se ha popularizado hasta hoy.

arriba1.1.4- Que fuentes de información existen

Los libros que son ya clásicos sobre Perl son los libros del camello y la llama de la editorial Nutshell, además, existen magníficas introducciones y manuales de referencia que se pueden obtener vía internet. Aun cuando es imposible mencionar con precisión las fuentes de información de un medio tan dinámico con algo tan estático como este documento. Debe notarse, además que estas referencias están en inglés.

Para buscar información, Yahoo! por supuesto:

http://www.yahoo.com/Computers_and_Internet/Languajes/Perl/

Fuente de información general y referencia de documentos:

http://pubweb.nexor.co.uk/public/perl/perl.html

http://www.khoros.unm.edu/staff/neilb/perl/perl5.html

Una buena formada introducción:

http://www.khoros.unm.edu/staff/neilb/perl/introduction/home.html

Documentación:

http://www-cgi.cs.cmu.edu/cgi-bin/perl-man

http://www.perl.com/perl/info/documentation.html

ftp://ftp.cdrom.com/pub/perl/CPAN/doc/manual/html/index.html

ftp://ftp.uoknor.edu/mirrors/CPAN/doc/manual/html/index.html

Debo recalcar que por la misma naturaleza de Perl, los recursos disponibles y las herramientas que se pueden utilizar cambian muy a menudo, por lo que es indispensable dedicar algún esfuerzo a mantenerse al día para evitar un desperdicio mayor de esfuerzo por no utilizar los nuevos recursos disponibles.

arriba1.2- Filosofía de Perl

"Hay mas de una forma de hacerlo"

-Larry Wall, autor del lenguaje de programación Perl.

Perl no establece ninguna filosofía de programación (de hecho, no se puede decir que sea orientado a objetos, modular o estructurado aun cuando soporta directamente todos estos paradigmas), los objetivos que se tuvieron en cuenta al diseñar la sintaxis de Perl fueron la facilidad de aprendizaje y de uso y la claridad de código, las cuales, considero que son necesarias (aunque pueden escribirse programas en Perl complejos e inteligibles si así se desea).

Por si fuese poco, Perl no es ni un compilador ni un interprete, esta en un punto intermedio, cuando mandamos a ejecutar un programa en Perl, se compila el código fuente a un código intermedio en memoria, se le optimiza (como si fuésemos a elaborar un programa ejecutable) pero es ejecutado por un motor, como si se tratase de un interprete. El resultado final, es que utilizamos algo que se comporta como un interprete pero que tiene un rendimiento comparativo al de programas compilados. Sin embargo, ya existen compiladores de Perl con la versión 5.

En fin, Perl no nos forza a nada, pero como es lógico hay ciertas reglas que recomiendo seguir para facilitar nuestro trabajo:

Claridad. En la mecánica de programación actual, los programas deben de ser entendibles por la persona que nos suceda en tareas de mantenimiento, de lo contrario perjudicamos tanto a nuestros compañeros de trabajo como a nuestra propia libertad para progresar y mantenernos libres de preocupaciones. Indentación. Una costumbre ya clásica de la programación, en lo personal, y a lo largo de los ejemplos de este documento, indento el código dos espacios hacia adelante al abrir cada bloque, y termino la indentación al terminar el bloque, de modo que las llaves de apertura y cierre quedan a la vista y en la misma columna, solas en sus renglones (esto incrementa algo el numero de
líneas, pero facilita sobremanera la búsqueda y corrección de los diversos bloques de control).
Nombres de variables y demás. En lo personal, procuro dar la máxima claridad a los nombres de las variables sin hacerlos demasiado grandes, el nombre de los contadores y variables que guardan valores concernientes a un pequeño segmento de código por lo regular son de un par de letras (c1, c2, ... cx para los contadores, s1, s2, etc para cadenas de entrada etc.) mientras que las variables que afectan a diversos segmentos (a modo de regla, que tienen su definición en una pantalla distinta a donde se usan) tienen nombres explicativos que procuro no excedan los 12 caracteres. Además, los nombres de archivos se usan con mayúsculas (ARCHENT, ARCHSAL, etc) y las clases tienen su primera letra mayúscula.
Comentarios. Para facilitar la comprensión de un programa no hay como explicarlo, y los comentarios son el medio ideal para hacerlo, hay por lo menos tres comentarios que considero que siempre deben incluirse en un programa: Que hace el programa, Quien lo escribió y Cuando inicio y termino de escribirlo, sobretodo en el contexto de una organización, estos tres simples comentarios pueden hacer la diferencia entre desechar un programa como indescifrable o dedicarle algún tiempo para revisarlo. Además, considero prudente comentar dentro del código la forma en que el programa deberá ejecutarse, parámetros, y su sintaxis, así como comentar las estructuras de control como un modo de explicar la funcionalidad al detalle y recalcar con comentarios las funciones que cumplen las variables.
Sencillez. Es cómodo en ocasiones el comprimir una serie de instrucciones en una sola línea, queda al criterio decidir cuando se gana en claridad con un código mas o menos extenso, pero no debe titubearse en comentar el código que sea "comprimido".

arriba1.3- Diferencias entre Perl 4.3 y 5.X, Como elegir versión

Actualmente existen dos versiones altamente populares de Perl, la 4.3 y la 5.0X, de hecho hay diferencias importantes entre una versión y otra. Seguramente el lector se pregunta porque surge la duda entre usar una versión vieja y una nueva, por regla general las nuevas versiones son mejores que las anteriores de modo que las opacan en todo sentido, Perl no es la excepción a esta regla, el único factor que impide una transición inmediata es que no son 100% compatibles. La versión 5 de Perl es una reescritura total que ya incluye un manejo de estructuras abstractas de datos mucho mas poderoso, incluso, soporta la orientación a objetos a su manera (tema que no trato en esta introducción). De modo que las librerías, por ejemplo para creación de CGIs no funcionan de una función a otra por lo que la migración es poco practica.

Así pues, la decisión sobre que versión utilizar depende del trabajo que haya sido realizado con anterioridad, si ya se tiene un sistema completo o grande en Perl 4, es recomendable mantenerlo en Perl 4 por el resto de su vida útil, pero para desarrollos nuevos es por mucho, mas recomendable iniciarlos con Perl 5 o en su caso, la versión mas reciente que este disponible, por experiencia se que la capacitación para adaptarse a la nueva versión es extraordinariamente corta dada la importancia de las mejoras. Una tercera opción (que es por mucho la mas recomendable si se tienen los recursos) consiste en instalar las dos versiones de modo que convivan en el sistema.

arriba2- Programación básica

En este capitulo daremos una rápida revisión a los conceptos mas usuales que se encuentran en un programa en Perl, trataremos de ver la implementación para ambas versiones 4 y 5 cuando sea posible, especificando siempre en que versión esta el ejemplo original (dando preferencia a la versión 5) y al menos las alternativas para implementarlo en la otra versión.
Los ejemplo requerirán para funcionar, que se tenga Perl instalado en la maquina en que se practique y deberá conocerse la ruta completa al binario de Perl.
Mas que sentirse en libertad de experimentar con los diversos ejemplos, deben sentirse obligados a experimentar, modificar y explorar por su cuenta cada que sea posible, tomando los ejemplo solo como un punto seguro de partida. Para este fin, recomiendo que se tenga acceso desde el inicio a alguna referencia del lenguaje (ya sea el libro Programming Perl (del Camello) de la Nutshell o alguna referencia disponible por WWW), este documento pretende explicar lo básico de un modo accesible para que después pueda el nuevo programador de Perl abordar sin temor los materiales mas detallados.

arriba2.1- Estructura Básica de un programa, programa Holamundo.

Como se menciona en la introducción, Perl no obliga a casi nada, así pues, lo que planteo como estructura básica es mas bien una convención que un requisito del lenguaje, a diferencia de Pascal (por ejemplo) Perl no tiene una plantilla para sus programas y si se adoptan algunos protocolos es solo por comodidad.

Los programas de Perl, por lo regular, inician con la línea:

#!/usr/bin/perl
Esta línea, indica al SO que lo que sigue es un script de Perl, y que "Perl" (el programa con el cual debe ejecutarse) esta en el directorio "/usr/bin", la secuencia "#!" es una secuencia que UNIX reconoce, no Perl.

Un método alterno, que funciona para otras plataformas, es: en lugar de colocar esa primera línea ejecutamos:
Perl nombre_del_script.pl de modo que directamente se ejecuta el interprete de Perl pasándole como primer parámetro el script a ejecutar (los demás parámetros se tomaran como parámetros al programa). Si se requiere deberá sustituirse "Perl" por la ruta completa del programa y el nombre que el programa tenga.
Para los ejemplos sucesivos, tomare la suposición de que se trabaja en un sistema UNIX con el interprete de Perl en el directorio "/usr/bin".
Y eso es toda la estructura básica!.

Programa Hola mundo:

#!/usr/bin/perl
print "Hola Mundo\n"; #Saluda
#Programa Hola Mundo, Daniel Sol Llaven, 1996, como parte del tutorial de Perl
Este programa, se escribe como un archivo de texto común, (al que recomiendo se le ponga extensión ".pl") y se cambian sus permisos para que pueda ser ejecutado (por lo regular con un "chmod 700 nombre_programa.pl" en sistemas UNIX), para ejecutarlo simplemente se invoca el nuevo script "nombre_programa.pl", hay que recordar que para el sistema particular en que se este trabajando es muy probable que deba modificarse "/usr/bin/" por otra ruta.

Así, la ejecución en un sistema UNIX podría verse como:

>chmod 700 Hola.pl
>Hola.pl
Hola Mundo
>Hola.pl
Hola Mundo
>
Ejecutando dos veces el script pretendo mostrar que no es necesario cambiar el modo de ejecución del script sino solo una vez.
Expliquemos las tres líneas que constituyen nuestro primer script:

#!/usr/bin/perl
Esta línea, propiamente dicho, no es parte del script de Perl, sino una instrucción al SO para indicar que las siguientes líneas deberán interpretarse por el programa "/usr/bin/Perl", si se omite, o no funciona en el sistema operativo, podemos ejecutar el programa de la siguiente forma:

>/usr/bin/Perl Hola.pl
Hola Mundo
>print "Hola Mundo\n"; #Saluda
Esta es la única instrucción del programa y esta acompañada por un comentario, la instrucción es:

print "Hola Mundo\n";
que pudo ser escrita como:

print("Hola Mundo\n");
sin que esto implicara el mínimo cambio en funcionalidad.

a continuación tiene el comentario:

#Saluda
La sintaxis de C para comentarios no funciona en Perl, pues se usa a "/" para expresiones regulares.

#Programa Hola Mundo, Daniel Sol Llaven, 1996, como parte del tutorial de Perl
Esta línea es otro comentario, el SO y Perl consideran todo lo que este en una línea que inicie con "#" como comentario. (excepto en el caso de que sea una primera línea, el SO lo interpreta como la indicación del interprete, pero Perl lo ignora como a cualquier otro comentario).

arriba2.2- Estructuras de Datos Básicas

En nuestro programa Hola.pl no utilizamos ninguna variable, por lo que para explicar estos conceptos necesitaremos un nuevo programa, HolaP.pl que es una versión personalizada de Hola.pl.

#!/usr/bin/perl
#Programa Hola Mundo personalizado, Daniel Sol Llaven 1996, Tutorial Perl.
print "Hola ?como te llamas?:";
$nombre=<STDIN>;
chop($nombre);
print "$nombre!, bonito nombre, cuantos años tienes?:";
$edad=<STDIN>;
print "sabias que te faltan ".(100-$edad)." para tener 100?\nAdios!\n";
Su ejecución genera resultados similares a los siguientes:

>HolaP.pl
Hola ?como te llamas?:Daniel
Daniel!, bonito nombre, cuantos años tienes?:22
sabias que te faltan 78 para tener 100?
Adiós!
>
En este programa, aparecen muchos elementos novedosos que iremos revisando poco a poco a lo largo de este documento, por el momento, revisemos que hace línea por línea:

#!/usr/bin/perl
#Programa Hola Mundo personalizado, Daniel Sol Llaven 1996, Tutorial Perl.
Cabecera normal del programa, incluido comentario indispensable.

print "Hola ?como te llamas?:";
Esta línea escribe "Hola ?como te llamas?:" pero nótese que no escribe una vuelta de carro al final (omite el "\n").

$nombre=<STDIN>;
Aquí asignamos a $nombre un renglón escrito por la entrada estándar del programa.

Perl define al "archivo" STDIN como su entrada estándar, y el operador <> que indica la lectura de una línea de un archivo de texto, de modo que <STDIN> indica la lectura de un renglón de la entrada estándar (al menos para el ejemplo!), este tema se tratara con cuidado en la sección 2.5 y 3.3 de este documento que tratan de operaciones con archivos.

Para fines prácticos, usaremos <STDIN> como la expresión que lee una línea de entrada del usuario desde teclado.

chop($nombre);
Perl, al leer la línea escrita por el usuario, también toma el enter que el usuario da, de modo que en el ejemplo, la entrada que di en vez de ser "Daniel" se puede escribir como "Daniel\n", (siendo "\n" el carácter de vuelta de carro), la función "chop()" tiene la función de eliminar el ultimo carácter a nuestra cadena, de modo que después de esta instrucción $nombre solo tiene "Daniel". Por las características de la lectura de renglones de archivos, chop() es un elemento casi constante en programas de Perl.

(Pruébalo!, revisa que sucede si comentas esta línea, veras que al imprimir el nombre imprime también el retorno de carro avanzando una línea hacia abajo).

print "$nombre!, bonito nombre, cuantos años tienes?:";
Esta línea nos muestra como se imprime el contenido de nuestras variables de forma sencilla; notamos que en la cadena a imprimir se encuentra $nombre, el compilador lo interpreta y reemplaza por su valor, (para imprimir "$" se pone "\$"), el resto de la cadena es completamente convencional.

$edad=<STDIN>;
Esta línea, lee otra línea de TEXTO y la coloca en la variable $edad (con todo y retorno de carro).

print "sabias que te faltan ".(100-$edad)." para tener 100?\nAdios!\n";
Esta línea imprime un mensaje que esta dividido en tres partes, la primera y la ultima son cadenas convencionales, que están concatenadas (operador .) con una operación aritmética. Hay que notar que edad era un renglón de la entrada estándar, y no un numero, sin embargo no hay conflicto de tipo al operarlo con un entero, ¿porque? porque los dos, para Perl, son del mismo tipo, son escalares, después discutiremos que son los escalares y que mecanismo de conversión se utiliza para extraer el entero del texto contenido en $edad.

(Experimenta!, prueba que pasa si los valores que se dan a edad no son enteros, que pasa si son reales o cadenas!)

Después de nuestro primer encuentro con las variables de Perl, el sentimiento mas probable es el de perplejidad, ¿como maneja sus variables?,
¿a que me refería conque enteros, reales y cadenas son del mismo tipo?, y si es así, ¿como serán los demás tipos?.

En realidad, las variables de Perl pretenden simplificarnos la vida, pero debemos comprender como pretenden facilitar las cosas para no terminar peleando contra ellas.

2.2.1- Clases de Datos

Perl reconoce tres clasificaciones básicas de datos, y dos especiales, por claridad, llamaremos clases a estas diversas clasificaciones, y tipos a las formas usuales de datos.
Las diversas clases se distinguen entre si por el símbolo que antecede al nombre de la variable (por ejemplo $nombre es una variable de tipo escalar que se llama "nombre"), debe notarse que no hay relación entre variables del mismo nombre si son de clases distintas.

A continuación, pongo una tabla de las clases de datos y los tipos que contienen:

Clase Símbolo Tipos
Escalar $ Entero, Real, Cadena, Referencia*
Arreglo @ Arreglo de escalares
Hash % Arreglo Asociativo de escalares
Archivo (ninguno) Identificador de Archivo
Type Glob * Cualquiera**

* Las referencias son exclusivas de Perl 5, son el equivalente a apuntadores.
** Las variables tipo Glob se usaban como sustituto de las referencias en Perl 4, son obsoletas para Perl 5 y en lo personal no recomiendo su uso sino en casos muy particulares.

2.2.1.1- Escalares

Nota: Algunas características de las conversiones entre tipos son exclusivas de Perl 5, pero la sintaxis y características generales son las mismas para ambas versiones. Por lo que en general, el tratamiento expuesto es valido para las dos.

El escalar, es la clase de datos que engloba los tipos convencionales de datos, de modo que podemos decir:

$v1="Daniel Sol Llaven";
$v1=100;
$v1=89.12;
Sin que esto implique ningún cambio en la naturaleza de $v1, en todo momento es un escalar.

Aun cuando la compatibilidad de datos enteros y reales es fácil de imaginar, la conversión implícita en el caso de las cadenas no lo es, sin embargo la regla es bastante simple.

por ejemplo:

$v1="123y321";
crea un escalar $v1, que contiene la cadena "123y312", ¿pero que pasa si le deseamos sumar 4?. Perl, interpreta $v1 como entero (o punto flotante) para esto, toma todos los caracteres del inicio que forman un numero correcto y ese numero es el que interpreta; de modo que:

print $v1+1;
imprimirá:

124
Del mismo modo, como ejemplo:

$v2="123.123.123"+1
da el valor 124.123 a la variable $v1 (punto flotante).

Otro punto importante de las variables en general es que, aunque en ningún momento se declaran como de un tipo o de otro, si se pueden "destruir", o revisar que hayan recibido algún valor en la ejecución del programa, esto se logra mediante las funciones defined() y undef(). defined nos indica si la variable que le pasamos como argumento ha sido definida (es decir, existe en el programa) o no. undef toma una variable y la "elimina" de modo que ya no tiene valor y defined la reporta como no utilizada.

Los valores lógicos de verdadero y falso se manejan de modo similar al de C, cualquier valor escalar no nulo o cero se considera verdadero. Debe tenerse cuidado con las cadenas "0" pues si se evalúan como número resultaran en falso aun cuando no son cadenas nulas.

Los escalares son los constituyentes de las demás estructuras de datos, por lo que al explicar los arreglos, hashes, referencias y archivos haremos muchas referencias a ellos.

2.2.1.2- Arreglos

Los arreglos en Perl son simplemente, arreglos dinámicos de escalares, es decir, se pueden usar cualesquiera elementos en el arreglo y Perl se encargará de hacer al arreglo de la dimensión adecuada.

La definición de un arreglo con valores constantes es:
@a1=("hola",123,43.2,"adios");
Esta definición, crea el arreglo @a1 con cuatro elementos, dos cadenas, un entero y un real, en realidad, cuatro escalares, para hacer referencia a los elementos escalares de un arreglo se usan los corchetes [] indicando el índice del elemento (de cero al numero de elementos menos uno) de modo que:

print "$a1[0]\n$a1[1]\n$a1[2]\n$a3[3]\n";
resulta para el arreglo anterior:

hola
123
43.2
adiós
Nótese que el elemento de un arreglo ya no es un arreglo, sino un escalar, y debe especificarse como tal, con $ en vez de @. No es lo mismo el escalar a1 que un elemento del arreglo a1.

$a1 Es un elemento distinto que $a1[]

Por claridad, recomiendo que no se dupliquen nombres de arreglos (o cualquier otra cosa) con escalares, aunque Perl da un manejo independiente a las diversas entidades, de modo que si se hace no habrá quejas de parte de Perl.

Es importante señalar que los arreglos y hashes no pueden ser elementos de un arreglo, si se intenta esto, los arreglos o hashes serán "aplanados" a elementos que se agregan al arreglo. Por ejemplo:

(a,b,(c,d),e)==(a,b,c,d,e)
Es decir, el arreglo constante a,b, arregló con c,d , e es equivalente al arreglo que contiene a,b,c,d,e. Pues al formar el primer arreglo, el sub-arreglo c,d es "aplanado" a elementos que se agregan al arreglo principal. Algo similar sucede a los hashes.

Para hacer arreglos de arreglos o arreglos como elementos de hashes, se utilizan las referencias.

2.2.1.3- Hash o Arreglos Asociativos

El Hash, o arreglo asociativo es una ampliación del arreglo, en la que en vez de ubicar los elementos por posición se les ubica por una "llave" es pues un arreglo de parejas ordenadas que se accesa por el primer elemento, el símbolo de los hashes es %, y la forma de declarar un hash con constantes es muy similar a la forma para declarar un arreglo:

%h1=("ll1",1,"ll2",2,"ll3",3);
Esta declaración crea un hash con tres parejas ordenadas, las llaves son "ll1", "ll2", "ll3", para usarlo se pueden usar expresiones del tipo:

$ndx="ll3";
print "$h1{ll1}\n$h1{"ll2"}\n$h1{$ndx}\n";
resultando:
1
2
3
Al igual que en los arreglos, cada elemento de un hash es un escalar, de modo que debe anteponerse $ en vez de % (pues no estamos haciendo referencia a todo el hash, sino a un elemento escalar del hash), pero a diferencia del los arreglos, en vez de usar [] para indicar el índice se usan las llaves {}.

Dentro de las llaves, en el ejemplo, usamos las tres formas principales de dar el índice: ll1 - En esta forma Perl adivina correctamente que ll1 es una cadena y que esta es la llave.
"ll2" - En esta forma decimos explícitamente el valor de la llave deseada.
$ndx- como $ndx="ll3" Perl puede determinar el valor de la llave correcta.
Para índices, al igual que para hashes, también puede usarse el valor de variables o de expresiones para especificar el índice.


2.2.1.4- Equivalencias de Clases

Como ya revisamos, al hacer referencia a un elemento particular de un arreglo o hash obtenemos un escalar (en ves de todo el arreglo o hash). Este tipo de "cambios" de clase son el propósito de esta sección, pues pueden resultar algo confusos aunque, una vez comprendidos, dan una buena parte del sabor peculiar de Perl.
Básicamente, Perl distingue dos tipos de contextos para evaluar una expresión: como escalar y como arreglo. El primero se refiere a las expresiones que han de regresar un escalar (del tipo que sea) como resultado, y el segundo a aquellas expresiones que han de regresar un arreglo o conjunto de escalares como resultado. Muchas expresiones pueden ser evaluadas en ambos contextos y obtener, según el contexto, un resultado distinto, esto lo revisaremos con cuidado conforme vayamos revisando estas expresiones.
Revisemos los cambios que ocurren a los datos de una cierta clase cuando los evaluamos en otro contexto:

-------------------------------------------------------------------
Contexto escalar arreglo

Clase escalar arreglo hash

escalar escalar El valor Se convierte en Vacío, no definido
original el único elemento del arreglo arreglo arreglo Numero de El arreglo de Los elementos pares elementos valores (0,2,4,...) forman (usualmente) originales las llaves y los nones los datos del nuevo hash.
hash cociente que arreglo con las El hash original representa la parejas eficiencia del llave1,valor1,lla hash ve2,valor2,...
-------------------------------------------------------------------

Las transiciones mas utilizadas son las de arreglo a escalar, las de arreglo a hash y de hash a arreglo, la primera porque permite conocer el tamaño de los arreglos y las segundas porque proveen los mecanismos para inicializar los hashes con arreglos constantes y para "aplanarlos" con fines de almacenamiento e impresión.
A menudo, se representa un arreglo con una sola cadena que contiene separadores para los diversos elementos, Perl implementa la función "split" que divide estas cadenas en arreglos, su sintaxis básica es:

split($delim,$cadena)

donde $delim es la expresión que representa los delimitadores de elementos y $cadena es la cadena a dividir.
Como ya se mencionó, generará un arreglo de cadenas donde los elementos son las subcadenas de $cadena que estén separadas por cadenas $delim.
por ejemplo, una cadena como:
$registro="Daniel:22:daniel\@simba";
@reg=split(":",$registro);
print "Nombre:$reg[0]\nEdad:$reg[1]\nEmail:$reg[2]\n";
genera un resultado similar a:

Nombre:Daniel
Edad:22
Email:daniel@simba
Cuidado! no todas las funciones de Perl convierten de igual forma los arreglos en escalares, por lo que debe provarse o investigar primero que efectivamente en el contexto en que hagamos la conversión el resultado sea el deseado.

Ejemplos:

Arreglo constante

@arreglo=(1,2,"hola",3,"adios");
inicializa el arreglo @arreglo con los elementos 1,2,"hola",3,"adios", (todos escalares). la notación de los elementos entre paréntesis define un arreglo constante, el equivalente a un numero o cadena constante cuyo valor asignáramos a una variable pero en el contexto de los arreglos.

"Hash" constante

%hash=("llave1","dato1","llave2","dato2); #arreglo constante a hash Inicializa el %hash con las llaves "llave1" y "llave2" poniéndole como contenidos "dato1" y "dato2" respectivamente. De hecho, no especificamos un "hash constante" como en el caso del arreglo, sino que especificamos un arreglo constante el cual pasa por una transformación de clase para asignarse a un hash, de modo que la expresión es equivalente a:

@arreglo=("llave1","dato1","llave2","dato2); #arreglo constante a arreglo
%hash=@arreglo; #arreglo a hash
Cardinalidad de un arreglo

@arreglo=(1,2,3,4);
$elementos=@arreglo;
En este caso $elemento recibe el valor 4, pues son 4 los elementos del arreglo, nótese que el índice máximo en el arreglo es de solo tres, pues el primer elemento es el elemento 0 y Perl 4 regresa, con esta misma expresión el índice máximo en lugar del número de elementos como Perl 5.

Asignación a arreglo constante

($a,$b,$c)=(1,2,3);
Esta expresión es equivalente a:

$a=1;
$b=2;
$c=3;
Pero debe tenerse cuidado, el siguiente código:

($a,$b,$c)=(1,2,3);
@a=($a,$b,$c);
$a=7;
$b=8;
$c=9;
Da al arreglo @a el valor del arreglo constante (1,2,3), y no, como podría pensarse. (7,8,9). Cuando se genera un arreglo constante se evalúan los elementos que lo forman como constantes escalares y se le asigna después, para obtener resultados diferentes se deberá usar un arreglo de referencias.

Arreglos con arreglos

@a=(1,2,3);
@b=(5,6,7);
@c=(@a,4,@b,8);
Estas expresiones generan tres arreglos, (1,2,3), (5,6,7) y (1,2,3,4,5,6,7,8), y no, como podría pensarse un arreglo de arreglos, cuando incluimos un arreglo dentro de otro, Perl "aplana" el arreglo insertado como si insertara uno a uno todos sus elementos en la posición indicada del arreglo que ha de contenerlos, para hacer arreglos de arreglos deberemos usar referencias a estos.

2.2.3- Tipos Especiales de Datos

Llamo a estos "tipos especiales" porque nos permiten hacer cosas inposibles con otros tipos, por ejemplo, el evitar ser "aplanado" en los arreglos. Además, incluyo en esta sección a los Archivos, pues aunque su sintaxis se parece a las de las variables, su funcionalidad es bien distinta. Sin embargo, por tratarse de solo una introducción omito discutir sobre los "type globs" que son la aproximación a las referencias que perl 4 implementa.

2.2.3.1- Referencias

Nota: Este tipo de datos es exclusivo de Perl 5, Perl 4 usaba los type globs para realizar algunas de estas funciones, pero el proceso es mucho mas complicado y obscuro.

Las referencias son el equivalente lógico de los apuntadores, son un tipo de dato que no contiene información en si misma, sino que permite manejar indirectamente los datos contenidos en otra entidad.
Las referencias, sin embargo, no forman una clase nueva de datos, sino que son tratados como un tipo mas de escalar.
La definición de referencias se realiza por el operador referencia "\" (backslash) , funciona de modo similar a "&" en C, y aunque a diferencia de C no hay un operador de derreferencia la sintaxis para acceder al dato original es muy sencilla.

A diferencia de C, los objetos que creemos mediante referencias no quedan como cadáveres en memoria, Perl lleva un registro de las diversas
referencias a cada elemento en memoria y automáticamente lo destruye cuando descubre que nadie hace ya referencia a él, de modo que pueden usarse las referencias sin miedo, aunque con la precaución necesaria para no perder los datos que almacenamos en ellas.

2.2.3.1.1- Creación

Podemos crear referencias de varias formas, las que considero mas sencillas y útiles son:

Usando el operador de referenciación en una variable, o valor, en el caso de una variable, es crear un medio alterno de acceder al valor de la variable.

$rescalar=\$escalar;
$rarreglo=\@arreglo;
$rhash=\%hash;
$rrutina=\&subrutina; #la programación de subrutinas la revisaremos mas adelante.
$globref=\*ARCHIVO; #solo revisaremos los type globs para usarlos como referencias a archivos.
Creando objetos "anónimos" que solo pueden ser accesados por medio de la referencia.

Escalares

$rescalar=\"hola"; #referencia a la cadena anónima "hola"
Arreglos:

$rarreglo=[1,2,3]; # referencia al arreglo anónimo (1,2,3)
Hashes

$rhash={"llave1"=> "dato1","llave2"=> "dato2"};
Nótese que en esta representación usamos además el operador "=>" que indica una pareja de llave y dato, las que se separan por comas; esta notación también es valida para hashes convencionales, pero la claridad que agrega es mejor utilizada al declarar hashes anónimos.

Como elementos de arreglos y/o hashes para formar estructuras de datos complejas, al ser escalares, son elementos del arreglo sin mas complicación,de modo que los arreglos a los que hacen referencia se mantienen intáctos.

Por ejemplo, para formar un hash que contenga arreglos de nombres de letras:

%rhletras={
"latinas"=> ["a","b","c"],
"gregas"=> ["alfa","beta","gamma"]};
Esta sentencia forma un hash donde las llaves son cadenas y los datos son referencia a arreglos.

Pueden convinarse las referencias a arreglos y a hashes anónimos a voluntad para formar una estructura de datos tan compleja como se desee.

2.2.3.1.2- Uso

De nada sirven las referencias si no podemos extraer y modificar los datos contenidos en los elementos señalados por la referencia, en Perl la forma para obtener el valor y para modificarlo es casi la misma, solo las abreviaturas de las referencias para obtener el valor funcionaran de modo distinto cuando tratemos de asignarles valor.

Aun cuando Perl tiene varias formas de "derreferenciar" la información, solo discutiré dos por considerarlas las mas sencillas, sin embargo, recomiendo una revisión al capitulo PERLREF de la referencia de Perl 5.X para una explicación mas detallada y a consciencia del manejo de las referencias.

Uso "simbólico" de las referencias.

Por regla general, podemos usar las referencias como si se sustituyeran antes de ejecutar el código (aunque en realidad, no sea así), de modo que el código:

$nombre="entero";
$entero=5;
$rentero=\$entero;
$$nombre=6;
$$rentero=7;
efectivamente cambia el valor de $entero de 5 a 6 y despues de 6 a 7, del mismo modo podemos usar las referencias refiriéndonos a cualquier otro tipo.

por ejemplo, para arreglos:

$rarreglo=[1,2,3,4] #crea arreglo anónimo (1,2,3,4)
$$rarreglo[2]="tres"; #modifica el arreglo anónimo a (1,2,"tres",4)
@$rarreglo=(); #limpia el arreglo anónimo
Uso con el operador de derreferencia.

Como una forma de abreviar el proceso para referencias a arreglos y hashes, se añadió el operador -> que indica que el escalar es una referencia a hash o arreglo y espera el índice después.

por ejemplo:

$rarreglo->[5]="algo";
coloca "algo" como el 6o elemento del arreglo al que hace referencia
$rarreglo.

$rhash->{"alfa"}="uno";
coloca la pareja ("alfa"=> "uno") en el hash al que hace referencia $rhash.

Uso abreviado del operador de derreferencia.

Se pueden obtener referencias a referencias, y se pueden hacer arreglos de referencias, de modo que los arreglos multidimencionales se pueden elaborar con la misma mecánica que en C.

$ra3d->[0]->[0]->[0]=1; #pone un "0" en la primera celda de un arreglo tridimencional
Nótese que al crear perl los arreglos de las dimensiones adecuadas automáticamente no hay problemas de invasión de memoria no reservada (aunque un uso descuidado puede ocupar cantidades demasiado grandes de memoria). Y esta aplicación se considero lo bastante frecuente para implementar una abreviatura, de modo que la expresión anterior es equivalente a:

$ra3d[0][0][0]=1;
Lo cual le da mas claridad de lectura al código (pero debe tenerse cuidado de no confundirlo con un elemento de un arreglo, $ra3d es una referencia a un arreglo de referencias y no un arreglo normal. Por claridad podríamos usar:

$ra3d->[0][0][0]=1;
Ejemplo: A continuación, coloco el listado de un programa que usa las estructuras de datos que mencionamos anteriormente usando su potencia lo mas posible sin que pierdan claridad, recomiendo que no solo se pruebe el programa, sino que se elabore una versión en la que se exploren los puntos que particularmente les resulten mas interesantes.

2.2.3.2- Archivos

Uno de los usos mas probados y comunes de Perl es el procesamiento de archivos de texto para generar otros archivos (por lo regular de texto) que implican cierto proceso de los datos leídos originalmente. Además, Perl no conoce mas entrada que la proveniente de archivos (asociando la entrada, salida y salida de errores a archivos "de ambiente") por lo que en cierta medida ya hemos revisado el uso básico de archivos, solo que ahora le daremos la explicación correspondiente a las entidades que vimos antes.

Como en cualquier otro lenguaje, el ciclo de uso normal de un archivo es:

Apertura Mediante "open" inicializa una variable de archivo

Uso Lectura secuencial por líneas

Cerrado Mediante close


Perl tiene implementaciónes para manejar archivos binarios y archivos aleatorios, pero el uso de archivos de texto secuenciales es lo mas común en UNIX, por lo que considero a este manejo como básico y le explico aquí.
Básicamente, se puede decir que hay tres tipos de archivos que se manejan de modo muy similar:

Archivos comunes
Programas de los que capturamos la entrada o la salida
La entrada, salida o salida estándar de errores.
Estos tres tipos de archivos se manejan igual (con la limitación de que algunos solo reciben lectura o escritura) y el momento en que se determina el tipo verdadero del archivo, es en el momento de la apertura, por lo que ha dedicado una sección exclusivamente a la apertura mientras que al uso y cierre los he concentrado en la sección que siguiente a esta.

Inicio ayudas


Aquí puede ir tu publicidad. Pídeme las tarifas.