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?

13
demandé sur DVK 2010-03-26 23:28:59

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 exemple MyModule1 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 est MyModule2 et le chemin hiérarchique sera This::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 et MyModule2.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:

    1. prenant le répertoire suivant de @INC - disons /usr/lib/perl comme exemple

    2. 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 .

    3. 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
13
répondu DVK 2018-04-08 22:03:11

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.

5
répondu toolic 2012-12-20 17:20:16

, 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 .

2
répondu Greg Bacon 2010-03-26 20:53:38