Comment Perl's @INC est-il construit? (aka Quelles sont les façons d'affecter où modules Perl sont recherchés?)
quelles sont les façons d'affecter l'endroit où les modules Perl sont recherchés? ou, Comment est-Perl @INC construit ?
comme nous le savons, Perl utilise @INC
tableau contenant des noms de répertoires pour déterminer où rechercher des fichiers de modules Perl .
il ne semble pas y avoir de FAQ" @INC " complète sur StackOverflow, donc cette question est prévue comme un.
3 réponses
nous allons regarder comment le contenu de ce tableau est construit et peut être manipulé pour affecter où L'interpréteur Perl trouvera les fichiers du module.
-
par Défaut
@INC
interpréteur Perl est compilé avec un
@INC
valeur par défaut . Pour connaître cette valeur, lancez la commandeenv -i perl -V
(env -i
ne tient pas compte de la variable d'environnementPERL5LIB
- 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 (qui n'est pas nécessairement le même que le répertoire du script). Il est absent dans Perl 5.26+, et lorsque Perl tourne avec -T
(vérification de la teinture activée) .
pour changer le chemin par défaut lors de la configuration du binaire Perl compilation, définir l'option de configuration otherlibdirs
:
Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3
-
variable environnementale
PERL5LIB
(ouPERLLIB
)Perl pre-pends
@INC
avec une liste de répertoires (séparés par deux points) contenus dansPERL5LIB
(si elle n'est pas définie,PERLLIB
est utilisé) environnement variable de votre shell. Voir le contenu de@INC
aprèsPERL5LIB
etPERLLIB
variables d'environnement ont pris effet, exécuterperl -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 .
-
-I
option en ligne de commandePerl pre-pends
@INC
avec une liste de répertoires (séparés par deux points) passés comme valeur de l'option de ligne de commande-I
. Cela peut être fait de trois façons, comme d'habitude avec les options Perl:-
Passer sur la 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
-
passer sous
PERL5OPT
(ouPERLOPT
) variable d'environnement (voir chapitre 19.02 dans programmation Perl )
-
-
passer par le
lib
pragmaPerl prepends
@INC
avec une liste de répertoires qui lui est transmise viause lib
.dans un programme:
use lib ("/dir1", "/dir2");
sur la ligne de commande:
perl -Mlib=/dir1,/dir2
vous pouvez aussi supprimer les répertoires de
@INC
viano lib
. -
vous pouvez manipuler directement
@INC
comme un tableau Perl régulier.Note: puisque
@INC
est utilisé pendant la phase de compilation, cela doit être fait à l'intérieur d'un blocBEGIN {}
, qui précède la déclarationuse MyModule
.-
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 annuaires sont unshifted sur @INC
dans l'ordre indiqué dans cette réponse, par exemple @INC
par défaut est le dernier dans la liste, précédé de PERL5LIB
, précédé de -I
, précédé de use lib
et de @INC
manipulation directe, les deux derniers mélangées dans l'ordre où elles sont en code Perl.
, les Références:
- perldoc perlmod
- perldoc lib
- Module Perl Mécanique - un guide contenant pratique COMMENT-TOs
- Comment "utiliser" un module Perl dans un répertoire qui n'est pas
@INC
? - programmation Perl - Chapitre 31 partie 13, ch 7.2.41
- comment un programme Perl sait-il Où trouver le fichier contenant le module Perl qu'il utilise?
il ne semble pas y avoir un @INC
FAQ-post de type sur le débordement de la pile, donc cette question est prévue comme un.
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 s'ils sont exécutés par plusieurs utilisateurs, ce répertoire doit être inclus dans le répertoire par défaut
@INC
compilé dans le binaire Perl. -
si les modules dans le répertoire seront utilisés exclusivement par un utilisateur spécifique pour tous les scripts que l'utilisateur exécute (ou si recompiler Perl n'est pas une option pour changer par défaut
@INC
dansPERL5LIB
, généralement lors de l'ouverture de session de l'utilisateur.Note: s'il vous plaît soyez conscient des pièges habituels de la variable D'environnement Unix - par exemple dans certains cas, exécuter les scripts comme un utilisateur particulier ne garantit pas de les exécuter avec l'environnement de cet utilisateur mis en place, par exemple via
su
. -
Si les modules dans le répertoire doivent être utilisés seulement dans certaines circonstances (par exemple, lorsque le(s) script (s) est exécuté en mode développement/débogage, vous pouvez définir
PERL5LIB
manuellement, ou passer l'option-I
à perl. -
si les modules doivent être utilisés uniquement pour des scripts spécifiques, par tous les utilisateurs les utilisant, 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 exécution - par exemple à partir des paramètres de la ligne de commande du script ou du chemin du script (voir le module FindBin pour le cas d'utilisation très agréable). -
un cas d'utilisation supplémentaire pour manipuler directement
@INC
est d'être en mesure d'ajouter des références de sous-programmes ou d'objets (Oui, Virginia,@INC
peut contenir du code Perl personnalisé et pas seulement des noms de répertoires, comme expliqué dans quand est-ce qu'une référence de sous-Programmes dans @INC est appelée? ).
@INC
si les répertoires dans @INC
doivent être manipulés selon une logique compliquée, soit impossible à trop lourd à mettre en œuvre par la combinaison de use lib
/ no lib
pragmas, puis utiliser direct @INC
manipulation à l'intérieur BEGIN {}
bloc ou à l'intérieur d'un spécial objet bibliothèque désignée pour la manipulation @INC
, qui doit être utilisée par votre(vos) 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 bibliothèque waterfall dans prod si elle est manquante dans dev et/ou UAT (la dernière condition rend la solution standard" utiliser lib + FindBin " assez compliquée. Une illustration détaillée de ce scénario est dans Comment faire J'utilise les modules beta Perl des scripts beta Perl? .
en plus des emplacements énumérés ci-dessus, la version OS X de Perl a aussi deux autres façons:
-
The /Library/Perl/X. xx / fichier AppendToPath. Les chemins listés dans ce fichier sont annexés à @INC à l'exécution.
-
The /Library/Perl/X. xx / fichier PrependToPath. Les chemins listés dans ce fichier sont prédéfinis à @INC à l'exécution.
comme il a déjà été dit @INC est un tableau et vous êtes libre d'ajouter tout ce que vous voulez.
mon script CGI REST ressemble à:
#!/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 est exporté par Rest.pm.