| Artículos | 01 MAY 2001

Programación en Perl (III)

Tags: Histórico
Javier Cáceres.
Sentadas en el anterior número las bases de la gestión de variables y las estructuras de control, lo que veremos en esta entrega es lo que resta para terminar de establecer el esqueleto de la programación en Perl: el tercer y último tipo de datos, las subrutinas para una programación modular, y el acceso a recursos de Entrada/Salida.

Despedimos la anterior entrega del curso adelantando en gran medida los contenidos de la presente. Hablaremos de temas bien dispares, pero al mismo tiempo indispensables para empezar a ver Perl como un lenguaje de programación serio y apto para la mayoría de las tareas, escapando del tópico que lo restringe al limitado ámbito de la realización de scripts de administración de sistemas. Descubrimos al fin el tercer gran tipo abstracto de datos que nos quedaba pendiente: los arrays asociativos. Tipo de datos de gran versatilidad, no presente de forma nativa en multitud de los lenguajes de programación más relevantes. De igual forma, presentamos las subrutinas, mecanismos existentes en la práctica totalidad de los lenguajes de programación imperativa que nos van a permitir la tan versátil como casi imprescindible programación modular. Y, por terminar con aspectos indispensables, la más importante asignatura pendiente: los mecanismos básicos de entrada/salida.

Arrays asociativos
Los arrays asociativos, tras las variables escalares y los arrays estándares, constituyen el tercer tipo abstracto de datos que Perl incorpora. También conocidos por el término hashes, los arrays asociativos toman ese nombre de la similitud existente entre su principal virtud y lo que en otros muchos lenguajes de programación se conoce por tablas hash. En un array asociativo, al igual que en tales tablas, los distintos valores que queremos almacenar han de asociarse con otro dato que entendemos como clave. Para acceder o modificar un determinado dato, hemos de conocer y emplear la clave bajo la cual ha sido asociado y almacenado. Conceptualmente operan de forma similar a los arrays convencionales, con la salvedad de que el índice, la clave con la que apuntamos a un dato concreto del array, en este caso no tiene por qué ser un número, puede ser cualquier tipo de escalar, incluidos los textos. La ventaja de este sistema a efectos organizativos, sobre todo cuando trabajamos con cantidades importantes de datos, es evidente. Resulta mucho más fácil recordar y trabajar con índices alfanuméricos (en esencia, nombres con los que recordar el dato que almacenamos), que con simples e impersonales números de orden.
Hemos visto hasta el momento que, dentro del código de un programa escrito en Perl, cada variable viene precedida de un metacarácter que define el tipo de dato que se trata. Si con las variables escalares y los arrays convencionales acompañábamos los nombres de variable con el carácter reservado $ y @ respectivamente, en el caso de los arrays asociativos o hashes hemos de emplear el carácter reservado %. Por otro lado, acceder a un punto concreto de esta especie de tabla clave/dato, es muy similar a como accedíamos a posiciones de un array convencional con la salvedad de que, en lugar de corchetes
([ ]), empleamos llaves ({ }), y, obviamente, que en lugar de referirnos un número de orden o índice, indicaremos una clave alfanumérica.
La idea de todo esto queda plasmada en el código contenido en el listado 1. En este ejemplo definimos la “tabla” %registro, que va a contener dos entradas. La primera de ellas consiste en un dato alfanumérico (Pedro), al que asociamos la clave Nombre. La segunda entrada es un dato numérico, concretamente el 34, al que se relaciona con la clave Edad. La asignación de ambos pares clave/dato se realiza en la 5ª y 6ª línea, mientras que la forma de recuperar tales datos se refleja en las dos sentencias subsiguientes. Recuerde que, cuando la variable registro va precedida de %, se hace referencia siempre a la totalidad del array asociativo, pero cuando se va a asociar un dato a una clave (que a fin de cuentas es un escalar), utilizamos el metacarácter específico de escalares: $.
Otro aspecto importante a tener en cuenta es que cualquier variable hash o de array asociativo puede convertirse fácilmente en un array simple, al igual que podemos definir un array asociativo con el formato de un array simple. Sustituya la 5ª y 6ª línea del listado 1 por la orden %registro = qw /Nombre Pedro Edad 34/; y vuelva a ejecutar el programa. El resultado es el mismo, se pueden definir hashes introduciendo, como si de un array estándar se tratase, todos los pares clave/dato secuencialmente. De la misma forma, podemos crear una variable de array que contenga una copia de una variable de tipo hash simplemente igualando una variable a la otra. Con algo como: my @hash_en_lista = %registro, al final del listado crearíamos un array hash_en_lista tradicional compuesto de 4 elementos escalares: Nombre, Pedro, Edad, 34. Tenga presente, pues, que cualquier función que trabaje correctamente con arrays, lo hará con hashes; simplemente hemos de transformar temporalmente un tipo de variable en otro.
Perl con sus arrays asociativos nos ofrece un mecanismo muy eficaz para la consulta de datos puntuales al almacenarlos en forma de lista de pares. Si bien esta forma de acceder a los datos nos puede resultar muy útil, en ciertas ocasiones nos gustaría poder aplicar cierta función al conjunto total de los datos contenidos en un hash. En estas circunstancias, siempre podremos transformar los datos en un array convencional y aplicar la susodicha función, pero el lenguaje nos propone alternativas mucho más simples: las funciones keys, values y each. El comportamiento de las dos primeras se puede observar en el listado 2. Keys devuelve, en formato array convencional, la lista de claves (@nombres en este ejemplo), de un hash dado, mientras que values, hace lo propio exclusivamente con los valores o datos almacenados (@apellidos). Observe que los datos son devueltos en orden inverso en ambos casos. Si bien con esto ya contamos con los recursos necesarios para realizar cualquier tipo de operación sobre el conjunto de datos de una variable hash cualquiera, en el caso de precisar aplicar ciertas operaciones sobre el total de los datos, la mejor alternativa será siempre each. Se puede implementar de muy diversas formas, pero quizás la más sencilla sea combinando la orden con la sentencia while:
While ( ($clave, $dato) = each(%registro) )
{
...
Aplicar_función_sobre_$clave_y_$dato;
...
}
También se podría haber empleado la orden foreach en lugar de while, pero el resultado a nivel funcional sería el mismo. Sólo restaría en este punto saber cómo extraer más de un dato al mismo tiempo si tenemos sus claves asociadas. El procedimiento es bien sencillo: dentro de las llaves, separar las claves con comas y, obviamente al devolver más de un dato, emplear un array estándar en lugar de un escalar a la hora de almacenar el resultado. En nuestro particular ejercicio, la sentencia sería algo como: @varios_apellidos = @registro{‘Pedro’, ‘Pablo’};.

Subrutinas
Subrutinas, procedimientos, funciones... Se podrían discutir las sutiles diferencias entre unas y otras, es cuestión de simple terminología pero, en esencia, se llamen como se llamen, la idea de estos recursos en cualquier lenguaje de programación es muy simple: aislar, dentro de nuestro propio programa, segmentos de código a fin de que puedan ser llamados en cualquier momento para realizar

Contenidos recomendados...

Comentar
Para comentar, es necesario iniciar sesión
Se muestran 0 comentarios
X

Uso de cookies

Esta web utiliza cookies técnicas, de personalización y análisis, propias y de terceros, para facilitarle la navegación de forma anónima y analizar estadísticas del uso de la web. Consideramos que si continúa navegando, acepta su uso. Obtener más información