web-dev-qa-db-fra.com

Comment est construit le @INC de Perl? (aka Quels sont tous les moyens d'affecter l'endroit où les modules Perl sont recherchés?)

Quelles sont toutes les manières d’affecter l’emplacement où les modules Perl sont recherchés? ou, Comment le @INC de Perl est-il construit ?

Comme nous le savons, Perl utilise @INC tableau contenant les noms de répertoire pour déterminer où rechercher les fichiers de module Perl .

Il ne semble pas y avoir de publication de type FAQ "@INC" complète sur StackOverflow, aussi cette question est-elle censée en être une.

198
DVK

Nous verrons comment le contenu de ce tableau est construit et peut être manipulé pour que l’interprète Perl trouve les fichiers de module.

  1. Par défaut @INC

    L'interpréteur Perl est compilé avec une valeur par défaut spécifique de @INC _ . Pour connaître cette valeur, exécutez la commande env -i Perl -V (env -i ignore la variable d'environnement Perl5LIB - voir n ° 2). Dans la sortie, vous verrez à peu près 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
     .
    

Notez . à la fin; c'est le répertoire courant (qui n'est pas nécessairement le même que le répertoire du script). Il est manquant dans Perl 5.26+, et quand Perl s'exécute avec -T (vérifications d'altération activées)) .

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

Configure -Dotherlibdirs=/usr/lib/Perl5/site_Perl/5.16.3

  1. Variable d'environnement Perl5LIB (ou PERLLIB)

    Perl ajoute au préalable @INC une liste de répertoires (séparés par des deux-points) contenus dans Perl5LIB (si elle n'est pas définie, la variable PERLLIB est utilisée) de votre Shell. Pour afficher le contenu de @INC après que les variables d'environnement Perl5LIB et PERLLIB 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
     .
    
  2. -I option de ligne de commande

    Perl ajoute @INC au préalable avec une liste de répertoires (séparés par des deux-points) passés en tant que valeur de l'option de ligne de commande -I. Cela peut être fait de trois manières, 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
      
    • Transmettez-le en tant que partie de la variable d'environnement Perl5OPT (ou PERLOPT) (voir le chapitre 19.02 dans Programmation Perl ).

  3. Passez le via le _ PRAGMA lib

    Perl ajoute au préalable @INC une liste de répertoires qui lui sont transmis via 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) .

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

    Remarque: Étant donné que @INC est utilisé pendant la phase de compilation, vous devez le faire à l'intérieur d'un bloc BEGIN {}, qui précède l'instruction use MyModule.

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

    • Ajoutez des répertoires à la fin via Push @INC, $dir.

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

Remarque: les répertoires sont non décalés sur @INC dans l'ordre indiqué dans cette réponse, par exemple. default @INC est le dernier de la liste, précédé de Perl5LIB, précédé de -I, précédé de use lib et d'une manipulation directe @INC, les deux derniers étant mélangés. ordre ils sont en code Perl.

Références:

Il ne semble pas y avoir de publication complète de type @INC de type FAQ sur Stack Overflow. Cette question est donc destinée à en être une.

Quand utiliser chaque approche?

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

  • Si les modules du répertoire doivent être utilisés exclusivement par un utilisateur spécifique pour tous les scripts exécutés par cet utilisateur (ou si la recompilation de Perl n'est pas une option permettant de modifier la valeur par défaut @INC dans le cas d'utilisation précédent), définissez la valeur Perl5LIB, généralement lors de la connexion de l'utilisateur.

    Remarque: Veuillez vous tenir au courant des pièges de variables d'environnement Unix habituels - par exemple. dans certains cas, l’exécution des scripts en tant qu’utilisateur particulier ne garantit pas de les exécuter avec la configuration de l’environnement de cet utilisateur, par exemple. via su.

  • Si les modules du répertoire ne doivent être utilisés que dans des circonstances spécifiques (par exemple, lorsque le (s) script (s) est exécuté (s) en mode développement/débogage, vous pouvez définir manuellement Perl5LIB ou passer l'option -I. à Perl.

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

  • Si les répertoires de @INC doivent être manipulés conformément à une logique compliquée, soit impossible à trop compliqué à mettre en œuvre par la combinaison de use lib/no lib pragmas, utilisez direct @INC manipulation dans BEGIN {} bloc ou dans une bibliothèque à usage spécifique désignée pour la manipulation @INC, qui doit être utilisée par vos scripts avant l'utilisation d'autres modules.

    Un exemple de ceci est la commutation automatique entre les bibliothèques des répertoires prod/uat/dev, avec le ramassage de la bibliothèque cascade dans prod s'il est manquant dans dev et/ou UAT (la dernière condition complique assez la solution standard "use lib + FindBin". A Une illustration détaillée de ce scénario se trouve dans Comment utiliser les modules beta Perl à partir de scripts beta Perl? .

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

252
DVK

Outre les emplacements répertoriés ci-dessus, la version OS X de Perl propose également deux autres moyens:

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

  2. Le fichier /Library/Perl/x.xx/PrependToPath. Les chemins répertoriés dans ce fichier sont précédés du préfixe @INC au moment de l'exécution.

17
dgatwood

Comme cela a déjà été dit, @INC est un tableau et vous pouvez ajouter ce que vous voulez.

Mon script CGI REST ressemble à ceci:

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

Le sous-programme disparu est exporté par Rest.pm.

6
Kacper Perschke