2017-10-19 9 views
3

Dans un programme Perl sur lequel je travaille, l'utilisateur peut spécifier un module Perl à charger qui devrait définir un couple (un nombre variable) de variables. Le programme Perl traite ensuite ces variables, en traitant fondamentalement le paquet comme un hachage simple sauf que les valeurs sont toutes dans un espace de noms. Cela fonctionne très bien, à savoir ce programme imprime « 2 »:Comment puis-je obtenir les symboles dans un paquet au moment où le paquet est défini?

use strict; 
use warnings; 

package P { 
    my $k1 = 'v1'; 
    my $k2 = 'v2'; 
}; 

my $n = scalar keys %P::; 
print "Number of entries: $n\n"; 
# print $P::x; 

Cependant, décommentant la dernière ligne fait l'impression du programme « 3 ». C'est à dire. la simple mention d'une variable dans le paquet semble l'ajouter à la table des symboles.

Existe-t-il un moyen d'obtenir la table de symboles pour un package tel qu'il est défini, de sorte que la table de symboles ne comporte que deux entrées?

+3

Peut-être, mais peut-être question plus importante est de savoir pourquoi voulez-vous faire et y a-t-il un meilleur moyen de le faire? –

+4

Cela ressemble énormément à un [problème XY] (https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Il serait sage de réitérer ce que vous essayez d'accomplir et pourquoi. Aussi - allumez «strict» et «avertissements» s'il vous plaît. – Sobrique

+0

@ Сухой27 Je travaille sur un débogueur Perl interactif (partiellement écrit en Perl lui-même, en partie en C++) qui permet aux utilisateurs de charger des 'configurations' stockées en tant que modules Perl. Les configurations sont essentiellement des ensembles de paires clé-valeur. Les clés de configuration doivent avoir un espace de nom (c'est pourquoi elles ne sont pas stockées dans un hachage simple mais plutôt dans un paquet qui est souvent traité comme un hachage). Le programme a besoin de l'ensemble total de paramètres stockés sur le disque à différentes fins (par exemple, pour décider si les paramètres sur le disque doivent être modifiés ou pour décider des paramètres à écrire). –

Répondre

5

Les variables de package rencontrées lors de la compilation seront ajoutées à la mémoire au moment de la compilation. Donc, vos solutions de contournement sont d'évaluer la planque dans la phase de compilation

package P { 
    $k1 = 'v1'; 
    $k2 = 'v2'; 
}; 

BEGIN {  
    my $n = scalar keys %P::; 
    print "Number of entries: $n\n"; # 2 
} 
print $P::x; 

ou pour définir d'autres variables de package à l'exécution

package P { 
    $k1 = 'v1'; 
    $k2 = 'v2'; 
}; 

my $n = scalar keys %P::; 
print "Number of entries: $n\n"; # 2 
print eval '$P::x'; 
$n = scalar keys %P::; 
print "Number of entries: $n\n"; # now 3 
+0

Ah, merci - il ne m'est pas venu à l'esprit que je pouvais utiliser 'BEGIN' sur le module principal aussi - ça m'a aidé! –