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?

46
demandé sur Machavity 2008-10-09 02:08:54

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;
86
répondu ephemient 2015-09-11 21:09:38

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.

19
répondu brian d foy 2008-10-08 22:21:38

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.

11
répondu Berserk 2008-10-08 22:22:43

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

6
répondu zigdon 2011-07-29 12:05:55

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.

2
répondu Jonathan Leffler 2008-10-08 22:11:14

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';
}
1
répondu 2008-12-20 22:57:23