Les modules et les objets en Perl

Outre sa formidable capacité à gérer les données en format texte, Perl possède bien d'autres atouts dans son sac à malices. Nous allons ce mois-ci examiner succinctement le fonctionnement des modules et des objets.

Importation d'un module

Pour charger un module, Perl offre deux commandes : require et use. La première correspond à l'ancien système de chargement, disponible en Perl 4, alors que la seconde ne l'est que depuis Perl 5.

La commande require fonctionne en cherchant le nom du fichier qu'on lui passe dans la liste de répertoires contenus dans @INC, et si elle le trouve, le charge, c'est-à-dire qu'elle le passe à eval, qui évalue le code et l'inclut au programme pendant l'exécution.

La commande use fonctionne un peu de la même manière, mais est appelée à la compilation. Elle fonctionne donc un peu comme import en Java. Elle est par ailleurs plus sophistiquée que require car elle permet de gérer des modules et des classes.

Grosso modo, les modules, ou packages, correspondent à des fichiers portant l'extension .pm qu'on utilise en écrivant simplement :

    use NomDePackage;

Les fonctionnalités offertes par le package sont alors directement accessibles. Dans bien des cas, cela signifie principalement qu'est définie une classe du même nom que le module, mais ce n'est pas une règle du langage comme en Java et un module Perl peut aussi bien définir plusieurs types de classes différentes que pas du tout.

Nous allons maintenant découvrir l'utilisation concrète des modules à l'aide de deux exemples très simples.

Un client SMTP

Pour le premier exemple, on va réaliser un client SMTP, c'est-à-dire un programme capable d'envoyer un email. En fait, on va se contenter d'utiliser le module Perl prévu à cet effet, Net::SMTP. Le :: indique une imbrication logique de package (ou de classe); le package SMTP est contenu dans le package Net, et en pratique, dans le répertoire qui contient tous les modules Perl (généralement /usr/lib/perl), le module SMTP.pm est dans le répertoire Net/. Dans les faits, on écrit simplement :

    #!/usr/bin/perl -w
    use Net::SMTP;

Pour réaliser l'envoi du mail, on va simplement créer l'objet approprié et utiliser ses méthodes.

    ## serveur mail
    my $server = 'mail';
    
    ## nom du destinataire
    my $recipient = 'fred' ;
    
    my $mail = new Net::SMTP $server;

L'objet que l'on vient de créer va alors se connecter au serveur qui lui a été spécifié. On peut alors lui passer les données de notre mail.

    $mail->mail($ENV{USER});
    $mail->to($recipient);
    $mail->data;
    $mail->datasend("To: $recipient\n");
    $mail->datasend("Subject: mail de test\n");
    $mail->datasend("\n");
    $mail->datasend("mail pour tester les modules SMTP et POP3 en Perl.\n");
    $mail->dataend;
    $mail->quit;

Les deux premières lignes permettent d'indiquer respectivement qui envoie le mail et à qui en l'envoie. Les lignes suivantes permettent de transmettre les données proprement dites du mail : les champ To: et Subject: et le message. On répète le champ To: par convention. L'instruction $mail->quit termine le mail et ferme la connection.

Un client POP

Maintenant qu'on sait envoyer un mail, il serait intéressant de pouvoir les lire. Pour cela, on va réaliser un client POP3. Comme pour le client SMTP, cela consiste principalement à créer un objet sur lequel on va appeler les méthodes nécessaires. Ici, le script inclut quelques messages et un prompt pour pouvoir lire les mails les uns après les autres, voire arrêter en cours de route. Il faut par contre mettre les valeurs appropriées pour le serveur, le login et le password.

    #!/usr/bin/perl -w
    use strict;
    use Net::POP3;
    
    my $server = 'mail';      ## nom du serveur pop3
    my $login  = $ENV{USER};  ## login sur le serveur
    my $passwd = '...';       ## mot de passe
    my $pop;
    
    $| = 1;
    
    print "connecting to $server.. ";
    $pop = Net::POP3->new($server);
    print "ok\n";
    
    $pop->login($login, $passwd);
    my ($undeleted, $size) = $pop->popstat;
    my $last = $pop->last;
    
    print "mail box size: $size\n", 
        "$undeleted unread mail(s).\n", 
        "last read mail: $last\n\n";
    
    for my $i (1..$undeleted) {
        ## on lit et on affiche le mail
        my $mail = $pop->get($i);
        print $s, "\n", '-'x(length $s), "\n", @$mail;
        
        ## on efface le mail
        $pop->delete($i);
      
        print "> ";
        chop(my $cmd = <>);
        last if $cmd =~ /q(uit)?/i;
    }
    
    $pop->quit;

Dans ce programme, chaque mail est marqué "à être effacé" après la lecture, mais est effectivement détruit lors de la déconnexion.

Si ces petits exemples ne risquent pas de faire de l'ombre aux classiques emailers qu'on utilise tous les jours, ils montrent à quel point il est facile d'envoyer et de lire des mails depuis un programme Perl. Ce qui peut se révéler intéressant pour réaliser des programmes pouvant gérer tout seul des mails générés automatiquement, par exemple par le formulaire d'une page web.

Sébastien Aperghis-Tramoni
25 août 1999
This document validates as XHTML 1.0 Strict and CSS.