Link Search Menu Expand Document

8.2. Perl

A partir de este punto, veremos varios lenguajes alternativos a PHP (es decir, su “competencia”) siguiendo siempre el mismo esquema:

  • Primero, enumeraremos las características y filosofia del lenguaje.
  • Luego explicaremos a grandes rasgos cómo hay que configurar el servidor para poder usar ese lenguaje para desarrollo web.
  • Después mostraremos la sintaxis básica del lenguaje.
  • Por último, escribiremos dos ejemplos completos en cada lenguaje: un sencillo “hola, mundo” y un programa algo más complejo que lanza una validación de login mediante ajax. En este segundo caso, la parte del cliente será siempre la misma, y solo cambiaremos la parte del servidor. Eso te permitirá apreciar las diferencias entre unos lenguajes y otros. Enseguida te darás cuenta de que esas diferencias son mínimas.

8.2.1. Características del lenguaje Perl

Fecha de aparición: 1987.

Perspectivas:

  • Uso decreciente.
  • Apto para tareas pequeñas y rápidas.
  • Cuenta con desarrolladores muy fieles y experimentados. Documentación muy extensa.
  • Soporte amplio en cualquier servidor.

Filosofía de Perl:

  • Versión mejorada del shell scripting de Unix.
  • Pensado para procesamiento rápido de archivos de texto y automatización de tareas de administración del sistema.
  • Favorece la programación ágil, rápida y sucia de scripts.
  • Énfasis en las expresiones regulares.
  • Multiparadigma.
  • En combinación con CGI, se popularizó para aplicaciones web antes de la aparición de PHP.

8.2.2. Configuración necesaria en el servidor

Para utilizar Perl en un servidor Apache o similar, necesitaremos:

  1. Instalar el intérprete Perl (usr/bin/perl).
  2. Activar los módulos perl y/o cgi de Apache y configurar el handler para CGI.
  3. Instalar módulos Perl adicionales para acceso a bases de datos, etc.

Se puede ejecutar el intérprete Perl de forma nativa en Apache, o bien hacerlo a través de CGI. Lo primero es más difícil de configurar y raramente se encuentra en hostings web compartidos.

8.2.3. Sintaxis básica de Perl

Las variables en Perl no se declaran, tienen tipado dinámico y son globales por defecto.

$var = valor;
print "La variable var vale $variable";

Algunos operadores:

  • Comparación: lt, gt, le, ge, eq, ne…
  • Asignación: =

Algunas estructuras de control:

while (condicion) {
  Acciones
}


if (condicion) {
  Acciones-1
}
else {
  Acciones-2
}

8.2.4. Entrada / salida

Entrada de datos estándar:

chop ( $variable = <STDIN> );

Lectura de datos desde un formulario HTML:

use CGI;
my $cgi = CGI->new;
my $username = $cgi->param("username");

Salida:

print "cadena $variable cadena..."; 

8.2.5. Bibliotecas, funciones y clases

Para utilizar una biblioteca o package, como se denominan en Perl, se emplea la palabra use:

use nombre-biblioteca;

Las bibliotecas se empaquetan en archivos con extensión .pm (Perl Modules). Dentro de ellas, puede haber una colección de funciones o métodos que se declaran así:

package nombre-biblioteca;

Sub nombre-funcion (argumentos) {
   Acciones
}

Estas funciones pueden usarse desde fuera de la biblioteca con esta sintaxis:

use nombre-biblioteca;

nombre-biblioteca::nombre-funcion(argumentos);

Los packages también pueden usarse para construir clases (o algo parecido) de las que luego se pueden instanciar objetos. Más o menos así:

  package nombre-de-la-clase;

  sub new {
      # Este es el método constructor
      my $self = {};      # Array para los atributos
      $self->{VAR1} = 0;  # Un atributo
      $self->{VAR2} = 9;  # Otro atributo
  }

  sub otro-método{
       # Aquí van el resto de métodos de la clase
  }
  sub DESTROY {
       # Método destructor
  }
  1    # Para que el intérprete Perl no se queje al interpretar este archivo

Como puedes observar, Perl está lleno de peculiaridades que muchos consideran anticuadas o, como mínimo, poco elegantes. Observa si no la forma que tiene de crear los atributos de instancia, los caprichosos nombres de los métodos (a veces en minúscula, a veces en mayúscula) o la necesidad de terminar el package con un 1 para que el intérprete Perl lo considere un script válido.

Por último, para instanciar un objeto de esta clase:

use nombre-de-la-clase;
$objeto = nombre-de-la-clase->new();

8.2.6. Ejemplo 1 en Perl: Hola mundo

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "<html><title>Hola mundo</title><body>";
print "Hola, mundo";
print "</body></html>";

8.2.7. Ejemplo 2 en Perl: login con comprobación de email por Ajax

Este segundo ejemplo, como hemos explicado más arriba, consistirá en un formulario de login que comprobará el nombre de usuario y la contraseña mediante una petición Ajax.

Formulario HTML

El formulario de login es un simple código HTML que será idéntico en todos los ejemplos que veremos en el resto de este capítulo, así que solo lo mostraremos aquí por primera vez.

<form id="loginForm" name="loginForm" method="post" action="">
  <fieldset>
    <p>
      <label for="username">Nombre de usuario</label>
      <br />
      <input type="text" id="username" name="username" class="text" size="20" />
    </p>
    <p>
      <label for="password">Contraseña</label>
      <br />
      <input type="password" id="password" name="password" class="text" size="20" />
    </p>
    <p>
      <button type="submit">Login</button>
    </p>
  </fieldset>
</form>

Script jQuery

El script que lanza la petición Ajax (cuyo código puede ir en el mismo archivo que el formulario) será casi idéntico en todos los ejemplos: solo cambiará el nombre del script al que se lanza la petición.

En nuestro caso actual, es script lo hemos llamado login.pl (la extensión .pl denota que se trata de un script escrito en lenguaje Perl). Como es lógico, en ejemplos posteriores, tendrías que cambiar el nombre de ese archivo por el que corresponda (login.py si estamos usando Python, login.rb si estamos usando Ruby, etc).

Para no repetirnos innecesariamente, no volveremos a mostrar tampoco el código de este script en los ejemplos sucesivos.

Observa que Javascript está esperando que el servidor responda con un JSON que puede llevar estos tres datos en su interior:

  • data.error: Un string con un texto de error en caso de que el usuario o la contraseña sean incorrectos.
  • data.success: Un string con un texto de éxito en caso de que el usuario y la contraseña sean correctos.
  • data.userId: Un entero con el ID del usuario logueado (solo en caso de éxito).
$(document).ready(function(){
  $("form#loginForm").submit(function() { 
    var username = $('#username').attr('value'); // Obtenemos el username
    var password = $('#password').attr('value'); // Obtenemos la password

    if (username && password) { // Los valores de username y password no están vacíos
      $.ajax({
        type: "GET",
        url: "login.pl", 
        dataType: "json",
        data: "username=" + username + "&password=" + password,
        success: function(data){
          if (data.error) { // El servidor ha devuelto un error de login
            $('div#loginResult').text("data.error: " + data.error);
            $('div#loginResult').addClass("error");
          } 
          else {            // El servidor ha hecho el login correctamente
            $('form#loginForm').hide();
            $('div#loginResult').text("data.success: " + data.success 
              + ", data.userid: " + data.userid);
            $('div#loginResult').addClass("success");
          } 
        } 
      }); 
    } 
    else {
      $('div#loginResult').text("Debe escribir su nombre de usuario y su contraseña");
      $('div#loginResult').addClass("error");
    } 
    $('div#loginResult').fadeIn();
    return false;
  });
});

Script Perl en el lado del servidor (login.pl)

Este sería el script en Perl que respondería a la petición Ajax anterior.

Observa que, a pesar de la peculiar sintaxis de Perl, la estructura del algoritmo es idéntica a la que usaríamos si lo escribiéramos en PHP:

  1. Recuperamos los datos del formulario (username y password)
  2. Conectamos con la base de datos
  3. Lanzamos la consulta contra la tabla de usuarios
  4. En función del resultado de la consulta, preparamos nuestro JSON de respuesta al cliente
  5. Devolvemos el JSON al cliente
#!/usr/bin/perl -T
use CGI;
use DBI;
use strict;
use warnings;

# read the CGI params
my $cgi = CGI->new;
my $username = $cgi->param("username");
my $password = $cgi->param("password");

# connect to the database
my $dbh = DBI->connect("DBI:mysql:database=mydb;host=localhost;port=2009",  
  "mydbusername", "mydbpassword") 
  or die $DBI::errstr;

# check the username and password in the database
my $statement = qq{SELECT id FROM users WHERE username=? and password=?};
my $sth = $dbh->prepare($statement)
  or die $dbh->errstr;
$sth->execute($username, $password)
  or die $sth->errstr;
my ($userID) = $sth->fetchrow_array;

# create a JSON string according to the database result
my $json = ($userID) ? 
  qq{{"success" : "login is successful", "userid" : "$userID"}} : 
  qq{{"error" : "username or password is wrong"}};

# return JSON string
print $cgi->header(-type => "application/json", -charset => "utf-8");
print $json;