Table des matières

Programmation modulaire

1. Modules et utilisation

Modules standards

Si l'interpréteur Perl possède en lui-même de nombreuses fonctions disponible, les builtin citées dans la longue page de manuel perlfunc, il en resterait largement insuffisant pour aborder des programmes d'envergure.

L'interpréteur Perl est donc normalement distribué simultanément avec une liste de modules qui sont considérés comme faisant partie de la distribution. En d'autres termes, si votre programme exige la présence de “Perl 5.8 ou supérieur”, il peut sans hésiter utiliser par exemple les modules Data::Dumper, IO::Socket, etc. La liste complète est décrite dans la page de manuel perlmodlib.

Note: parmi ces modules standards, il existent des modules dits pragmatiques et qui ont pour fonction de changer le comportement de l'intepréteur. Par exemple: restreindre les usages dangereux (use strict;), changer le comportement des signaux, des expressions régulières, etc.

Directive "use"

Pour utiliser un module Perl, il suffit de demander :

  use List::Util (shuffle);
 
  my @random = shuffle(1..10);

Le nom d'un module utilise la convention !CamelCase (ici List et Util), et le nommage est lui-même dans un espace hiérarchique. Cette hiérarchie n'est pas nécessairement lié à des relations de descendance au sens orienté objet, bien que ce soit en général le cas à chaque fois que cela est possible.

On peut passer optionnellement une liste de symboles (fonctions, variables, etc) auquel on veut pouvoir accéder directement (ici la fonction shuffle). Nous verrons qu'en général le module exporte les fonctions les plus demandées automatiquement pour nous et que cette possibilité est rarement exploitée.

Chemins de recherche

Nous le verrons plus loin, les modules Perl sont de simple fichiers Perl suivant une convention précise. L'interpréteur doit pouvoir les trouver au moment de la compilation, et il utilise plusieurs mécanismes pour ce faire :

$ perl -e 'print join("\n",@INC,"")'
/etc/perl
/usr/local/lib/perl/5.8.8
/usr/local/share/perl/5.8.8
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.8
/usr/share/perl/5.8
/usr/local/lib/site_perl
#!/usr/bin/perl -w -Iperl/tp1
...

Il est possible d'utiliser le même mécanisme, mais plus global, via les variables d'environnement PERLOPT/PERL5OPT, ex :

export PERL5OPT="-Iperl/tp1"
export PERL5LIB="perl/tp1:perl/tp2"
  use lib "./perl/tp1/tplib.pm";
  ...

2. Anatomie d'un module

Installation

Suivant la source et la méthode d'installation de vos modules Perl, ceux-ci vont se trouver à différents endroits dans votre système de fichiers. Il n'y a pas de règle stricte, mais en général:

Fichiers et répertoires

Perl recherche les modules demandes à l'aide des chemins de recherche qu'on lui a fournis, recensées dans @INC, et en décomposant la hiérachie des noms en répertoire et nommant le module lui-même avec l'extension .pm. Exemple :

$ perl -e 'use IO::Socket; print $INC{"IO/Socket.pm"}'
/usr/lib/perl/5.8/IO/Socket.pm

On peut consulter le chemin utilisé par Perl pour un module donné en consultant le tableau %INC (et non la liste @INC !).

Modules natifs

Certains modules ne sont pas écrits en Perl ou seulement partiellement réalisés en Perl car ils assurent uniquement un rôle d'interface vers une bibliothèque écrite dans un autre langage (généralement en C). Dans ce cas le fichier .pm ne suffit pas et doit être accompagné d'une bibliothèque dynamique (écrite en C et compilée pour la plateforme).

Il s'agit par exemple d'un fichier .so sous Unix, rangé selon le modèle hiérarchique mais dans un sous -répertoire auto/ (le chargement des modules natifs étant automatique et transparents grâce au module Autoloader que nous n'expliquerons pas en détail).

Bases d'un module

  package Test::Bidon;
 
  use warnings;
  use strict;
 
  BEGIN {
  use Exporter 'import';
  our @EXPORT = qw/bidon_hello bidon_bye/;
  our @EXPORT_OK = qw/test/;
  }
 
  sub bidon_hello {
  print "Hello les bidons\n";
  }
  sub bidon_bye {
  print "Au revoir les bidons\n";
  }
  sub test {
  print "Testons les bidons...\n";
  }
1;

Les éléments importants à retenir :

Si ce module est dans un fichier Test/Bidon.pl et que l'on exécute le test bidon.pl (on profite du fait que dans les chemins standards des modules il y a le chemin courant) :

#!/usr/bin/perl -w

use Test::Bidon;
use strict;

bidon_hello();
Test::Bidon::test();
bidon_bye();

Il est important de noter que les fonctions listées dans @EXPORT depuis le module sont automatiquement disponibles telles quelles (sans préfixe) pour l'utilisateur, ce qui n'est pas vrai par défaut pour les fonctions dans @EXPORT_OK. On peut toutefois explicitement importer ces fonctions (et donc les nommer sans le préfixe) :

use Test::Bidon qw/test/;
...
test();

Blocs BEGIN/END

Il est possible d'exécuter certaines partie du module dès son chargement (donc avant le démarrage du programme principal) ou après la fin du programme principal, en définissant des blocs nommés BEGIN ou END (cf. labels).

Documentation

Les modules de Perl (standards et surtout la majorité de CPAN) possèdent en général une très bonne documentation, et dans tous les cas fournissent une documentation (il s'agit d'une politique de diffusion obligatoire pour CPAN).

Documenter un module en Perl se fait comme dans la plupart des langages, dans le code lui-même à l'aide de marqueurs spécifiques. Cette technique s'appelle POD (Plain Old Documentation), et reprend l'organisation et la sémantique des pages de manuel.

Une section de documentation est une ligne commençant par le symbole = et un mot-clé de section. La documentation peut être présente à n'importe quel endroit du programme, on termine une ou plusieurs sections avec =cut. Pour les détails de formatage, se référer à man perlpod.

Pour le style standard (sections requises), se référer à man perlmodstyle. Exemple :

=head1 NAME

Test::Bidon - Un module de demonstration de programmation modulaire

=head1 SYNOPSIS

use Test::Bidon;
bidon_hello();
bidon_bye();

=head1 ABSTRACT

Module d'illustration de cours.

=head1 DESCRIPTION

Ce module implémente des méthodes qui présentent peu d'intérêt à part celui d'illustrer le fonctionnement des modules et en particulier d'Exporter.

==head2 Fonctions de base

=over

=item bidon_hello()

Dis bonjour.

=item bidon_bye()

Dis au revoir.

=back

=head1 SEE ALSO

Demo::Stupid, Porte::Naouak

=head1 AUTHOR

Vincent CARON <vcaron@insia.org>

=head1 COPYRIGHT AND LICENSE

Copyright (c) 2007 Bearstech - This module is released under the GNU GPL v2

=cut

L'extraction de documentation peut se faire via différents formats avec les commandes pod…, par exemple pour extraire une page de manuel et la consulter en même temps :

$ pod2man Test/Bidon.pm |man -l