Comment un programme Perl sait-il Où trouver le fichier contenant le module Perl qu'il utilise?
si mon programme Perl utilise des modules Perl, comment va-t-il déterminer où trouver le fichier contenant le code du module?
Par exemple, si le programme contient:
use MyModule1; # Example 1
use This::Here::MyModule2; # Example 2
où est-il?
3 réponses
Perl interpreter (qui exécute votre programme perl) utilisera un tableau spécial appelé @INC
pour rechercher un fichier contenant le module.
chaque valeur dans le tableau @INC
est un nom de répertoire ( mais voir la note ci-dessous ); Perl recherchera dans ces répertoires dans une boucle en utilisant les règles spécifiées ci-dessous. (Veuillez vous référer à pour plus de détails sur la façon dont le contenu de @INC est déterminé ).
si le fichier du module n'est pas trouvé après avoir épuisé @INC
, la compilation du programme sera annulée avec une erreur. Si le fichier du module se trouve dans l'un des répertoires spécifiés dans @INC
, la recherche est terminée sans regarder le reste de @INC
.
la façon dont Perl recherche un fichier de module dans chacun des répertoires énumérés dans @INC
est la suivante:
-
tout d'abord, il séparera les composants hiérarchiques du nom du module (mots séparés par
::
), dans le dernier composant - qui sera utilisé pour former un nom de fichier - et un chemin hiérarchique (tous les composants précédant le dernier::
).dans le cas où le nom du module n'a qu'un seul composant (no
::
, par exempleMyModule1
ci-dessus), le chemin de la hiérarchie est vide et le nom du fichier est le nom du module. Dans le deuxième exemple de cette question, le le dernier composant estMyModule2
et le chemin hiérarchique seraThis::Here
. -
le nom de fichier attendu sera déterminé en ajoutant le dernier composant du nom de module avec une extension
.pm
. Par exemple:MyModule1.pm
etMyModule2.pm
dans nos exemples.NOTE: les noms de modules sont évidemment sensibles à la casse sur Unix et d'autres systèmes d'exploitation où le nom du fichier/répertoire est sensible à la casse.
-
le répertoire du module sera déterminé par:
-
prenant le répertoire suivant de
@INC
- disons/usr/lib/perl
comme exemple -
formant un sous-répertoire de ce répertoire en prenant le chemin hiérarchique du nom du module (s'il y en a un) et en remplaçant":: "par
/
ou tout autre caractère que le système d'exploitation utilise comme séparateur de répertoire. Dans nos deux exemples, le premier module sera recherché dans/usr/lib/perl
(pas de sous-répertoire) et le second en/usr/lib/perl/This/Here
. -
NOTE : ce qui précède est une légère simplification -
@INC
peut également contenir des références de sous-Programmes et des références d'objet , qui chargent les modules comme leur code personnalisé spécifie au lieu d'effectuer la recherche dans le répertoire comme spécifié dans la logique #2 ci-dessus. Cette fonctionnalité semble être très rarement utilisée et cet article suppose que@INC
entier ne contient que des répertoires.
-
examinons un exemple spécifique, en supposant que votre @INC
contient deux sous-répertoires:
("/usr/lib/perl", "/opt/custom/lib")
.
alors Perl chercherait comme suit:
========================================================================== | Module | Try # | File to try ========================================================================== | MyModule1 | Try 1 | /usr/lib/perl/MyModule1.pm | MyModule1 | Try 2 | /opt/custom/lib/MyModule1.pm ========================================================================== | This::Here::MyModule2 | Try 1 | /usr/lib/perl/This/Here/MyModule2.pm | This::Here::MyModule2 | Try 2 | /opt/custom/lib/This/Here/MyModule2.pm ==========================================================================
Veuillez rappeler que l'interpréteur Perl va ARRÊTER d'essayer de recherche une fois qu'il trouve le fichier dans l'un des emplacements, sans essayer de voir si le fichier est au plus tard endroits aussi. Par exemple: si /usr/lib/perl/This/Here/MyModule2.pm
existe, alors Perl ne cherchera pas, ni ne se soucie de l'existence, de /opt/custom/lib/This/Here/MyModule2.pm
.
NOTE: @INC est utilisé chaque fois que Perl interpreter utilise un mécanisme similaire à require
pour importer des modules Perl. Cela comprend:
-
require
directive elle-même -
use MyModule
déclaration (équivalent à exiger+importation) -
use base
(équivalent à require+ "push @ISA") -
-M
paramètre de ligne de commande
bien que cela ne réponde pas directement à la question, voici quelques techniques simples pour déterminer le chemin complet vers le fichier de module que vous voulez utiliser.
pour voir le contenu par défaut du tableau @INC , avec beaucoup d'autres informations, à partir de la ligne de commande:
perl -V
Si vous voulez connaître l'emplacement de la Carpe module:
perldoc -l Carp
dans un script, l'impression du contenu du %INC hachage est utile pour déterminer le module réel que vous utilisez, surtout si vous avez modifié @INC de son défaut:
use Carp;
print $INC{'Carp.pm'};
ce script simple peut également être utilisé pour trouver des modules Perl installés correspondant à une expression régulière et pour identifier tout module dupliqué dans différents répertoires.
, Selon le perlfunc documentation sur use
:
utiliser le Module "LISTE des 1519170920"
importe de la sémantique dans le paquet courant à partir du module nommé, généralement en alienant certains noms de sous-programmes ou de variables dans votre paquet. C'est exactement l'équivalent de
BEGIN { require Module; Module->import( LIST ); }
sauf que le Module doit être un mot à la lettre.
Donc require
ne le levage lourd, et le require
documentation offre
si EXPR est un mot à la fois, le require suppose une extension
".pm"
et remplace"::"
par"/"
dans le nom de fichier pour vous, pour faciliter le chargement des modules standard. Cette forme de chargement de modules ne risque pas d'altérer votre espace de noms.en autres mots, si vous essayez ceci:
require Foo::Bar; # a splendid bareword
la fonction require recherchera en fait le fichier
"Foo/Bar.pm"
dans les répertoires spécifiés dans le tableau@INC
.