Perl un poco más a fondo


F. Javier García Castellano
Web: http://genura.ugr.es/~javi, Mail: javi@geneura.ugr.es
IndiceInicioPerl

(C) GeNeura Team
Web: http://geneura.ugr.es, Mail: todos@geneura.ugr.es

1.- Entradas y Salidas

Escribir en la salida estándar (pantalla) ya sabemos hacerlo, ahora nos interesa aprender como leer cosas desde el teclado y como escribir y leer en ficheros.

Para leer de teclado se utiliza <STDIN>, que es un manejador de ficheros (Filehandle), que por costumbre se ponen en mayúsculas. (También existe <STDOUT> y <STDERR> para la sálida estándar y la sálida de errores respectivamente).

Lectura de STDIN:

  #!/usr/bin/perl

  print "Hola. ¿Cómo te llamas?\n";
  $nombre=<STDIN>;

  #le quitamos el caracter de retorno de carro
  chop($nombre);

  if ($nombre eq "")
  {
    print '¿Qué pasa? ¿eres mudit@?'."\n";
  }
  else 
  {
   print "Hola $nombre, yo me llamo Flanagan. ¿Estudias o trabajas?\n";
  } 

En el anterior ejemplos el script de Perl se espera a que el usuario pulse Return (retorno de carro), es decir, lee una línea. Si en lugar de una variable se hubiese puesto un array, el script hubiese guardado también los retornos de carro hasta que se hubiese pulsado CTRL+D

Para escribir en la salida estándar se utiliza print como hemos visto, pero si queremos escribir en la salida de errores sería poniendo después de print el manejador de fichero de donde queremos escribir.

Lectura de STDIN, escritura en STDERR y STDOUT:

  #!/usr/bin/perl

  print "Hola. ¿Cómo te llamas?\n";
  $nombre=<STDIN>;
  #le quitamos el caracter de retorno de carro
  chop($nombre);

  if ($nombre eq "")
  {
    print STDERR '¿Qué pasa? ¿eres mudit@?'."\n";
  }
  else 
  {
    print STDOUT "Hola $nombre, yo me llamo Flanagan. ¿trabajas o vives?\n";
  } 

Ya sabemos leer/escribir en un manejador de fichero (vale, que hasta ahora sólo hemos usado pantalla y teclado). Ahora vamos a ver como se haría con ficheros. Para trabajar con un fichero hay que abrirlo, escribir/leer de él y cerrarlo. Para abrir un fichero se utiliza la función open y para cerrarlo con close. El formato para abrir un fichero es open (Manejador_de_fichero, Modo_y_NombreFichero). Lo modos de abrir un fichero se muestran en la siguiente tabla.

Modo Significado
"Nombre" Abre Nombre para leer.
"<Nombre" Abre Nombre para leer. Igual que el anterior
">Nombre" Abre Nombre para escribir. Si no existe lo crea
">>Nombre" Abre Nombre para añadir al final
"+>Nombre" Abre Nombre para lectura/escritura.

Veamos un ejemplo, de un script que copia un fichero en otro

Ejemplo de ficheros:

  #!/usr/bin/perl

  my $entrada="entrada.txt";
  my $salida ="salida.txt";

  open (ENTRADA,"<$entrada") || die "ERROR: No puedo abrir el fichero $entrada\n";
  open (SALIDA,">$salida") || die "ERROR: No puedo abrir el fichero $salida\n";
 
  while ($linea=<ENTRADA>)
  {
    print SALIDA $linea;
  }

  close (ENTRADA);
  close (SALIDA);

Si te fijas cuando abrimos los ficheros hemos utilizado algo especial, hemos puesto un O lógico y luego la función die seguido de un cadena; esto lo que hace es finalizar (die=morir) el programa si la parte de la izquierda del O lógico es falsa (no funciona correctamente) y, antes de finalizar, muestra la cadena que le sigue a die.

2.- Expresiones regulares

Las expresiones regulares de Perl es una de los principales factores que hacen de Perl un lenguaje muy potente en el tratamiento de cadenas. Una expresión regular es una forma de expresar gramaticalmente la estructura de cualquier cadena alfanumérica. La expresión regular se encierra entre barras y se aplica con =~ o con !~ para ver si se cumple o no, respectivamente. Por ejemplo, si queremos buscar la cadena "pepe" en una cadena, se haría como sigue:

  ...
  print "¡¡Está pepe!! \n" if ($cad=~/pepe/);
  ...

Como el uso de expresiones regulares es un mundo por si mismo, para los interesados pueden echarle un vistazo a http://geneura.ugr.es/~pedro/webmaster/expreg.htm

3.- Funciones split y join

Las funciones split y join se utilizan mucho y se les puede sacar mucho partido, por lo que haremos una mención especial de ellas.

3.1.- split

La función split lo que hace es separar una cadena en los trozos dados por una expresión regular. Para entenderlo, lo mejor, un ejemplo.

Ejemplo de split:

  #!/usr/bin/perl

  my $cadena="0";
  for (my $i=1; $i < 10 ; $i++)
  {
    $cadena.=", $i";
  }

  print "La cadena antes de partirla es $cadena\n";

  #Partimos la cadena en los elementos separados por las comas
  @elementos=split(/,/,$cadena);

  print "La cadena por partes es:\n";
  foreach $elemento (@elementos)
  {
     print "$elemento\n";
  }

3.2.- join

La función join nos permite unir diferentes partes en una sóla, introduciendo un separador entre ellas, es decir, hace lo contrario de split.

Ejemplo de uso de join:

  #!/usr/bin/perl

  #Creamos una array de 10 números
  my $i=0;
  push (@numeros,$i)  while ($i++ <= 10);

  #Juntamos todos los número del array separándolos por una coma
  $cadena=join(",",@numeros);

  #mostramos la cadena
  print "$cadena\n";

También nos puede ser util para leer un fichero completo en una variable.

Ejemplo de leer un fichero en una variable:

  #!/usr/bin/perl

  my $entrada="entrada.txt";
  my $salida ="salida.txt";

  open (ENTRADA,"<$entrada") || die "ERROR: No puedo abrir el fichero $entrada\n";
  open (SALIDA,">$salida") || die "ERROR: No puedo abrir el fichero $salida\n";

  $fichero=join("",<ENTRADA>);
  print SALIDA $fichero;

  close (ENTRADA);
  close (SALIDA);

si en el anterior ejemplo hubiesemos querido obtener un array con las líneas del fichero, nos hubiese bastado con poner después de join:

  ...
  @lineas)=split(/\\n/,$fichero);
  ...

4.- Módulos

En Perl, como en la mayoría de los lenguajes de programación tenemos los módulos o librerías o bibliotecas, según se prefiera llamar. Un módulo en Perl es un conjunto de funciones u objetos que se pueden acceder desde nuestro script. Se puede utilizar los módulos utilizando la sentencia use, como, por ejemplo:

....        
#Usamos las librerias de acceso a BD
use DBI;
....

Para usar módulos en Perl, también se pueden utilizar las sentencias do y require además de use., las diferencias son:

  1. do $nombreFichero lee el contenido de $nombreFichero en tiempo de ejecución.
  2. require $nombreFichero funciona de forma similar a do $nombreFichero excepto que comprueba antes si se ha leido el el contenido del módulo $nombreFichero. Si se ha leido, no lo vuelve a leer.
  3. use Modulo funciona de forma similar a require Modulo excepto que lo hace en tiempo de compilación, en lugar de tiempo de ejecución por lo que la ejecución del script es más rápida.

No es de extrañar que en algunos casos los módulos librerías son dos palabras separadas por ::; esto es porque los módulos están organizados en una especie de jerarquía, por ejemplo,el módulo LWP::UserAgent es para bajarse páginas de la WWW.

Todos (o casi todos) los módulos de Perl se encuentran en el CPAN (http://www.cpan.org) y probablemente allí encontraremos cualquier cosa que nos haga falta.

Si quieres aprender a como instalar módulos en tu sistema, puedes echarle un vistazo a http://geneura.ugr.es/~javi/dbi/modulos.htm

5. Ejercicios

Ejercicio: Lee un fichero contador formado por un número, incrementalo y vuelve a guardarlo.

Ejercicio: Lee un fichero formado por líneas de varios números separados por espacios, en una cadena (usando join) y saca de esa variable todos los números (usando split) y muestralos por pantalla.

Ejercicio: La función que hicistes de encontrar el máximo y el mínimo de un array, métela en un fichero aparte, y llámala como un modulo. Aplica la función de dicho módulo al ejercicio anterior y encuentra el máximo y el mínimo del fichero. (Nota: usar require)