Outils pour utilisateurs

Outils du site


perl:programmation_modulaire

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 :

  • Chemins par défaut: l'interpréteur connaît nécessairement le chemin des modules standards avec lequel il a été installé, ces chemins sont toujours configurés. Ces mêmes chemins sont en général également utilisés pour les modules supplémentaires installés par le mécanisme de la distribution GNU/Linux sous jacent. Exemple des chemins par défaut chez Debian :
$ 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
  • Option -I (i majuscule): on peut ponctuellement rajouter un ou des chemins de recherche de modules à l'aide de cette option, souvent à partir de l'appel à l'interpréteur incorporé en début de script :
#!/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"
  • PERLLIB/PERL5LIB: il est possible de passer par ces variables d'environnement pour rajouter une liste de chemin de recherches (supplémentaires en plus des chemins standards). La variable PERL5LIB a précédence sur PERLLIB. Exemple sous GNU/Linux (attention, le séparateur est ; sous MS Windows !) :
export PERL5LIB="perl/tp1:perl/tp2"
  • use lib “…”;: en dernier recours, et cette méthode est rarement recommandée, on peut spécifier un chemin arbitraire lors de l'utilisation d'un module, on désigne alors celui ci par son fichier. Exemple :
  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:

  • les modules packagés par votre distribution utiliseront les chemins des modules standard Perl
  • les modules que vous installerez localement via CPAN ou d'autres méthodes seront traditionnement dans /usr/local/lib/perl ou /usr/local/lib/site_perl (cette dernière convention étant classique chez Ruby et Python)

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 :

  • un module commence toujours par la directive package
  • un module finit toujours par uen condition vraie (sauf si le module estime mettre en danger l'application)
  • un module déclare les symboles disponibles (fonctions, variables) via l'utilisation du module standard Exporter et l'initialisation des listes @EXPORT et/ou @EXPORT_OK.

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
perl/programmation_modulaire.txt · Dernière modification : 2013/03/12 23:43 de root