198 votes

Comment est construit l'@INC de Perl ? (alias Quelles sont toutes les manières d'affecter l'endroit où les modules Perl sont recherchés ?)

Quelles sont toutes les façons d'affecter l'endroit où les modules Perl sont recherchés ? ou, Comment est construit l'@INC de Perl ? ?

Comme nous le savons, Perl utilise @INC tableau contenant des noms de répertoires pour déterminer où chercher les fichiers de modules Perl .

Il ne semble pas y avoir d'article complet de type FAQ "@INC" sur StackOverflow, cette question est donc destinée à en être une.

254voto

DVK Points 63282

Nous allons voir comment le contenu de ce tableau est construit et peut être manipulé pour affecter l'endroit où l'interpréteur Perl trouvera les fichiers du module.

  1. Défaut @INC

    L'interpréteur Perl est compilé avec un @INC valeur par défaut . Pour connaître cette valeur, exécutez env -i perl -V ( env -i ne tient pas compte de la PERL5LIB variable environnementale - voir #2) et dans la sortie vous verrez quelque chose comme ceci :

    $ env -i perl -V
    ...
    @INC:
     /usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld
     /usr/lib/perl5/site_perl/5.18.0
     /usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld
     /usr/lib/perl5/5.18.0
     .

    Note . à la fin ; c'est le répertoire courant. Il est absent lorsque Perl s'exécute avec -T (vérification de l'altération activée) .

    Pour changer le chemin par défaut lors de la configuration de la compilation binaire de Perl, définissez l'option de configuration otherlibdirs :

    Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3

  2. Variable environnementale PERL5LIB (ou PERLLIB )

    Perl prépasse @INC avec une liste de répertoires (séparés par deux points) contenus dans PERL5LIB (s'il n'est pas défini, PERLLIB est utilisé) variable d'environnement de votre shell. Pour voir le contenu de @INC après PERL5LIB y PERLLIB les variables d'environnement ont pris effet, exécutez perl -V .

    $ perl -V
    ...
    %ENV:
      PERL5LIB="/home/myuser/test"
    @INC:
     /home/myuser/test
     /usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld
     /usr/lib/perl5/site_perl/5.18.0
     /usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld
     /usr/lib/perl5/5.18.0
     .
  3. -I option de ligne de commande

    Perl prépasse @INC avec une liste de répertoires (séparés par deux points) passés en tant que valeur de la fonction -I en ligne de commande. Cela peut se faire de trois façons, comme d'habitude avec les options Perl :

    • Passez-le en ligne de commande :

      perl -I /my/moduledir your_script.pl
    • Passez-le via la première ligne (shebang) de votre script Perl :

      #!/usr/local/bin/perl -w -I /my/moduledir
    • Passez-le dans le cadre de PERL5OPT (ou PERLOPT ) (voir le chapitre 19.02 du document Programmer en Perl )

  4. Passez-la via le lib pragma

    Perl prépasse @INC avec une liste de répertoires qui lui sont passés par l'intermédiaire de use lib .

    Dans un programme :

    use lib ("/dir1", "/dir2");

    Sur la ligne de commande :

    perl -Mlib=/dir1,/dir2

    Vous pouvez également supprimer les répertoires de @INC via no lib .

  5. Vous pouvez manipuler directement @INC comme un tableau Perl normal.

    Note : Depuis @INC est utilisé pendant la phase de compilation, cela doit être fait à l'intérieur d'un fichier de type BEGIN {} qui précède le bloc use MyModule déclaration.

    • Ajouter des répertoires au début via unshift @INC, $dir .

    • Ajouter des répertoires à la fin via push @INC, $dir .

    • Faites tout ce que vous pouvez faire avec un tableau Perl.

Note : Les répertoires sont non décalé sur @INC dans l'ordre indiqué dans cette réponse, par exemple, par défaut @INC est le dernier de la liste, précédé de PERL5LIB précédé de -I précédé de use lib et direct @INC les deux dernières étant mélangées dans n'importe quel ordre dans le code Perl.

Références :

Il ne semble pas y avoir d'approche globale @INC Un post de type FAQ sur Stack Overflow, donc cette question est destinée à en être une.

Quand utiliser chaque approche ?

  • Si les modules d'un répertoire doivent être utilisés par plusieurs ou tous les scripts de votre site, en particulier s'ils sont exécutés par plusieurs utilisateurs, ce répertoire doit être inclus dans le fichier de configuration par défaut. @INC compilé dans le binaire Perl.

  • Si les modules du répertoire seront utilisés exclusivement par un utilisateur spécifique pour tous les scripts que cet utilisateur exécute (ou si la recompilation de Perl n'est pas une option pour modifier les valeurs par défaut de l'option @INC dans le cas d'utilisation précédent), définissent les paramètres de l'utilisateur PERL5LIB généralement lors de la connexion de l'utilisateur.

    Note : Soyez conscient des pièges habituels des variables d'environnement Unix - par exemple, dans certains cas, exécuter les scripts en tant qu'utilisateur particulier ne garantit pas leur exécution avec l'environnement de cet utilisateur, par exemple via su .

  • Si les modules dans le répertoire ne doivent être utilisés que dans des circonstances spécifiques (par exemple lorsque le script(s) est exécuté en mode développement/débogage, vous pouvez soit mettre PERL5LIB manuellement, ou passez le -I à perl.

  • Si les modules doivent être utilisés uniquement pour des scripts spécifiques, en todo utilisateurs qui les utilisent, utilisez use lib / no lib pragmas dans le programme lui-même. Il devrait également être utilisé lorsque le répertoire à rechercher doit être déterminé dynamiquement pendant l'exécution - par exemple à partir des paramètres de la ligne de commande du script ou du chemin du script (voir la section FindBin pour un cas d'utilisation très intéressant).

  • Si les répertoires dans @INC doivent être manipulés selon une logique compliquée, impossible ou trop lourde à mettre en œuvre en combinant les éléments suivants use lib / no lib puis utiliser des pragmas directs @INC manipulation à l'intérieur BEGIN {} ou à l'intérieur d'une bibliothèque à vocation spéciale désignée pour @INC qui doit être utilisé par votre script(s) avant que tout autre module ne soit utilisé.

    Un exemple de ceci est la commutation automatique entre les bibliothèques dans les répertoires prod/uat/dev, avec la récupération de la bibliothèque waterfall dans prod si elle est absente de dev et/ou UAT (cette dernière condition rend la solution standard "utiliser lib + FindBin" assez compliquée. Une illustration détaillée de ce scénario se trouve dans Comment utiliser des modules Perl bêta à partir de scripts Perl bêta ? .

  • Un cas d'utilisation supplémentaire pour manipuler directement @INC est de pouvoir ajouter des références à des sous-routines ou à des objets (oui, Virginia, @INC peuvent contenir du code Perl personnalisé et pas seulement des noms de répertoire, comme expliqué dans la section Quand une référence à une sous-routine dans @INC est-elle appelée ? ).

17voto

dgatwood Points 188

En plus des emplacements énumérés ci-dessus, la version OS X de Perl dispose de deux autres moyens :

  1. Le fichier /Library/Perl/x.xx/AppendToPath. Les chemins listés dans ce fichier sont ajoutés à @INC au moment de l'exécution.

  2. Le fichier /Library/Perl/x.xx/PrependToPath. Les chemins listés dans ce fichier sont ajoutés à @INC au moment de l'exécution.

6voto

Kacper Perschke Points 59

Comme il a déjà été dit, @INC est un tableau et vous êtes libre d'ajouter ce que vous voulez.

Mon CGI REST script ressemble à :

#!/usr/bin/perl
use strict;
use warnings;
BEGIN {
    push @INC, 'fully_qualified_path_to_module_wiht_our_REST.pm';
}
use Modules::Rest;
gone(@_);

La sous-routine gone est exportée par Rest.pm.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X