2010-06-04 15 views

Répondre

0

Pour être clair, vous regardez les paquets aléatoires dans le code Perl aléatoire?

Ou pour Perl modules, par ex. "a/b/c/d1.pm" avec le module "a :: b :: c :: d1"? Dans les deux cas, vous ne pouvez pas utiliser une seule instruction "use" pour les charger tous. Ce que vous devez faire est de trouver tous les fichiers appropriés, en utilisant glob ou File::Find.

Dans le premier cas (modules), vous pouvez les charger soit par require -ment chaque fichier ou en convertissant le nom de fichier en nom du module (s#/#::#g; s#\.pm$##;) et appelant use sur chaque module individuellement.

En ce qui concerne les paquets réels imbriqués dans des fichiers Perl aléatoires, ces paquets peuvent être:

  • Listed par grepper chaque fichier (encore une fois, a trouvé via glob ou File::Find) pour /^package (.*);/

  • En fait, chargé en exécutant require $file pour chaque fichier.

    Dans ce cas, s'il vous plaît noter que le nom du package pour chacun de ces paquets dans a/b/c/1.pl ne pas besoin d'être lié à « a :: b :: c » - par exemple ils peuvent être nommés par l'auteur du fichier "p1", "a :: p1" ou "a :: b :: c :: p1_something".

1

Normalement, un script tel que a/b/c.pl n'aura pas d'espace de noms autre que main. Peut-être que vous envisagez de découvrir modules avec des noms tels que a/b/c.pm (qui est un mauvais nom, puisque les noms de paquets en bas-case sont généralement réservés pour les internes Perl).

Cependant, étant donné un chemin de répertoire, vous pouvez rechercher des potentiels modules Perl utilisant File::Find:

use strict; 
use warnings; 
use File::Find; 
use Data::Dumper; 

my @modules; 
sub wanted 
{ 
    push @modules, $_ if m/\.pm$/ 
} 
find(\&wanted, 'A/B'); 

print "possible modules found:\n"; 
print Dumper(\@modules)' 
7

Si vous voulez charger tous les modules dans votre include_path avec un certain préfixe (par exemple tout sous a::b::c, vous pouvez utiliser Module::Find.

Par exemple:

use Module::Find 'useall'; 

my @loaded = useall 'Foo::Bar::Baz'; # loads everything under Foo::Bar::Baz 

Cela dépend de votre chemin @INC étant mis en place avec les répertoires nécessaires, donc faire toute manipulation nécessaire (par exemple avec use lib) en premier.

1

Cela pourrait être surpuissant, mais vous pouvez vérifier la table des symboles avant et après le chargement du module et voir ce qui a changé:

use strict; use warnings; 
my %original = map { $_ => 1 } get_namespaces("::"); 
require Inline; 
print "New namespaces since 'require Inline' call are:\n"; 
my @new_namespaces = sort grep !defined $original{$_}, get_namespaces("::"); 
foreach my $new_namespace (@new_namespaces) { 
    print "\t$new_namespace\n"; 
} 

sub get_namespaces { 
    # recursively inspect symbol table for known namespaces 
    my $pkg = shift; 
    my @namespace =(); 
    my %s = eval "%" . $pkg; 
    foreach my $key (grep /::$/, keys %s) { 
    next if $key eq "main::"; 
    push @namespace, "$pkg$key", get_namespaces("$pkg$key"); 
    } 
    return @namespace; 
} 

 
New namespaces since 'require Inline' call are: 
     ::AutoLoader:: 
     ::Config:: 
     ::Digest:: 
     ::Digest::MD5:: 
     ::Dos:: 
     ::EPOC:: 
     ::Exporter:: 
     ::Exporter::Heavy:: 
     ::File:: 
     ::File::Spec:: 
     ::File::Spec::Cygwin:: 
     ::File::Spec::Unix:: 
     ::File::Spec::Win32:: 
     ::Inline::Files:: 
     ::Inline::denter:: 
     ::Scalar:: 
     ::Scalar::Util:: 
     ::Socket:: 
     ::VMS:: 
     ::VMS::Filespec:: 
     ::XSLoader:: 
     ::vars:: 
     ::warnings::register::