Comment puis-je "utiliser" un module Perl dans un répertoire qui n'est pas dans @INC?
J'ai un module dans le répertoire parent de mon script et je voudrais l'utiliser.
Si je le fais
use '../Foo.pm';
Je reçois des erreurs de syntaxe.
J'ai essayé de faire:
push @INC, '..';
use EPMS;
Et .. apparemment, n'apparaît pas dans @INC
Je deviens fou! Quel est le problème ici?
6 réponses
use
a lieu au moment de la compilation, donc cela fonctionnerait:
BEGIN {push @INC, '..'}
use EPMS;
, Mais la meilleure solution est de use lib
, ce qui est plus agréable d'écrire ci-dessus:
use lib '..';
use EPMS;
Dans le cas où vous exécutez à partir d'un répertoire différent, cependant, l'utilisation de FindBin
est recommandée:
use FindBin; # locate this script
use lib "$FindBin::RealBin/.."; # use the parent directory
use EPMS;
Il y a plusieurs façons de modifier @INC
.
Ensemble PERL5LIB, comme documenté dans perlrun
Utilisez le commutateur-I sur la ligne de commande, également documenté dans perlrun. Vous pouvez également l'appliquer automatiquement avec PERL5OPT, mais utilisez simplement PERL5LIB si vous voulez le faire.
use lib
à l'intérieur de votre programme, bien que cela soit fragile car une autre personne sur une machine différente pourrait l'avoir dans un autre répertoire.Modifiez manuellement
@INC
, en vous assurant de le faire au moment de la compilation si vous voulez extraire un module avec use. C'est trop de travail même si.
Personnellement, je préfère garder mes modules (ceux que j'écris pour moi-même ou pour des systèmes que je peux contrôler) dans un certain répertoire, et aussi les placer dans un sous-répertoire. Comme dans:
/www/modules/MyMods/Foo.pm
/www/modules/MyMods/Bar.pm
Et puis où je les utilise:
use lib qw(/www/modules);
use MyMods::Foo;
use MyMods::Bar;
En aparté.. quand il s'agit de pousser, je préfère la graisse flèche virgule:
push @array => $pushee;
, Mais c'est juste une question de préférence.
'use lib' est la réponse, comme @ ephemient mentionné précédemment. Une autre option consiste à utiliser require/import au lieu d'utiliser. Cela signifie que le module ne serait pas chargé au moment de la compilation, mais plutôt en cours d'exécution.
Cela vous permettra de modifier @INC comme vous l'avez essayé, ou vous pourriez passer un chemin d'accès au fichier au lieu du nom du module. À partir de 'perldoc-F require':
Si EXPR est un mot bareword, le require suppose une extension". pm " et remplace ":: "par" / " dans le nom de fichier pour vous, pour le rendre facile pour charger les modules standard. Cette forme de chargement des modules ne risque pas modifier votre espace de noms.
Le push
traitées avant le use
- et use
est traité tôt. Ainsi, vous aurez besoin d'un BEGIN { push @INC, ".."; }
pour avoir une chance, je crois.
Tel Que rapporté par "perldoc -f":
, Il est exactement équivalente à
BEGIN { require Module; import Module LIST; }
sauf que ce Module doit être un mot nu.
Autrement dit, " use " est équivalent à:
- cours d'exécution au moment de la compilation,
- convertir le nom du paquet en un nom de fichier,
-
require
- ing ce nom de fichier, et -
import
-Ce paquet.
Donc, au lieu d'appeler use, Vous pouvez appeler require et importer dans un BEGIN bloc:
BEGIN {
require '../EPMS.pm';
EPMS->import();
}
Et bien sûr, si votre module ne fait pas réellement d'exportation de symboles ou d'autre initialisation lorsque vous appelez import, vous pouvez laisser cette ligne:
BEGIN {
require '../EPMS.pm';
}