Est-il obligatoire qu'un dossier portant le nom d'un package soit présent pour créer un package?
Question
Nous intégrons le code commun de notre projet Perl. Un programme principal doit être divisé en plusieurs modules réutilisables.
Notre nom de programme est validate_results.pl
, qui contient un ensemble de commandes de validation. Nous prévoyons de scinder cela en petits modules afin que validate_results.pl
soit semblable à:
use Common::Validate_Results;
use Common::Validate_Results::CommonCommands;
use Common::Validate_Results::ReturnCodeValidation;
...
D'après ce que j'ai compris, je devrais créer un dossier Common et sous lequel Validate_Results.pm
devrait figurer. Encore une fois sous Common
, le dossier Validate_Results
doit être créé et sous ce dossier CommonCommands
et ReturnCodeValidation
.
Est-il obligatoire que tous ces dossiers soient présents ou pouvons-nous avoir tous les programmes Perl dans un seul dossier et les regrouper logiquement tout en utilisant la méthode ci-dessus pour accéder aux modules (par exemple, utilisez common :: validate_results
comme ça).
La solution
La hiérarchie du système de fichiers est obligatoire. A :: B :: C sera toujours situé dans A / B / C.pm, quelque part dans @INC.
Si vous devez contourner ce problème, lisez perldoc -f nécessite , en particulier la section sur les références aux sous-programmes dans @INC. Oui, vous pouvez faire que le chargeur de modules fasse des choses étranges si c'est ce que vous voulez vraiment; mais ce n'est pas ce que vous voulez, croyez-moi. Tenez-vous-en à la convention, comme le font 99,9999999% des applications Perl.
Autres conseils
Si vous souhaitez "utiliser" vos modules, vous devez vous conformer à la structure. Si vous souhaitez contourner le problème, vous pouvez "exiger" vos modules à la place, en transmettant le nom de fichier requis.
Vous ne devriez vraiment pas faire ça, cependant. Si vous ne voulez vraiment pas avoir de structure de répertoires, supprimez-la des noms de modules (bien que cela puisse poser problème à l'avenir si vous avez un nom de module en conflit avec quelque chose de plus générique de CPAN). Ajoutez simplement le répertoire des scripts au chemin INC via Find :: Bin et utilisez directement les modules:
use FindBin;
use lib $FindBin::Bin;
use ValidateResults;
use CommonCommands;
use ReturnCodeValidation;
HTH
Voici un exemple de module et ses sous-modules dans le même fichier:
package Foo;
use strict;
use Exporter 'import';
our @EXPORT = ( 'from_foo' );
sub from_foo { print "from_foo\n"; }
package Foo::Bar;
use strict;
use Exporter 'import';
our @EXPORT = ( 'from_foo_bar' );
sub from_foo_bar { print "from_foo_bar\n"; }
1;
Dans votre programme, si vous utilisez le module Foo (celui avec un fichier .pm):
use Foo;
Vous aurez accès aux fonctions Foo :: Bar , sauf uniquement sous des noms canoniques (Foo :: Bar :: from_foo_bar). Vous pouvez les importer comme ceci:
use Foo;
Foo::Bar->import;
Notez que vous ne pouvez pas faire ceci:
use Foo::Bar;
Parce qu'il n'y a pas de fichier Foo / Bar.pm .
Le nom du paquet dans une commande 'use' est en réalité un chemin qui se termine par un fichier .pm, vous n'avez donc pas besoin d'un dossier avec le nom de chaque paquet. Dans votre exemple, vous avez besoin de dossiers:
Common
Common/Validate_Results
Mais vous n'avez pas besoin de dossiers:
Common/Validate_Results/CommonCommands
Common/Validate_Results/ReturnCodeValidation
Il n'est pas nécessaire que le nom du package dans le fichier .pm soit identique à celui de la commande "use" qui le charge. Mais garder les chemins cohérents avec les noms de paquets est toujours une bonne idée.