Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何在定义包时获取包中的符号?_Perl_Package - Fatal编程技术网

Perl 如何在定义包时获取包中的符号?

Perl 如何在定义包时获取包中的符号?,perl,package,Perl,Package,在我正在开发的一个Perl程序中,用户可以指定要加载的Perl模块,该模块将定义一对变量(变量数)。然后,Perl程序处理这些变量,基本上将包视为一个普通的散列,只是值都在一个名称空间中。这样做效果很好,即此程序打印“2”: use strict; use warnings; package P { my $k1 = 'v1'; my $k2 = 'v2'; }; my $n = scalar keys %P::; print "Number of entries: $n\n

在我正在开发的一个Perl程序中,用户可以指定要加载的Perl模块,该模块将定义一对变量(变量数)。然后,Perl程序处理这些变量,基本上将包视为一个普通的散列,只是值都在一个名称空间中。这样做效果很好,即此程序打印“2”:

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;
但是,取消最后一行的注释会使程序打印“3”。也就是说,在软件包中单独提及一个变量似乎会将其添加到符号表中


是否有一种方法可以按定义获取包的符号表,使符号表只包含两个条目?

编译时遇到的包变量将在编译时添加到存储中。因此,您的解决方法是在编译阶段评估存储

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

BEGIN {    
    my $n = scalar keys %P::;
    print "Number of entries: $n\n";  # 2
}
print $P::x;
或者在运行时定义其他包变量

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

也许,但可能更重要的问题是,你们为什么要这样做,还有更好的方法吗?这听起来很像一个例子。重申你想要实现的目标和原因是明智的。另外-请打开“strict”和“warnings”。@Саа27我正在开发一个交互式Perl调试器(部分用Perl编写,部分用C++),它允许用户加载存储为Perl模块的“配置”。配置基本上是一组键值对。配置键应该有名称空间(这就是为什么它们不是存储在一个普通的散列中,而是存储在一个通常被当作散列处理的包中)。程序需要存储在磁盘上用于不同目的的全部设置(例如,在决定磁盘上的设置是否更改,或在决定写入哪些设置时)。包内的单个散列按预期工作,@ССаа27是的,的确,只是散列名
h
有点难看。值得一提的是,我还考虑了更改配置,以便名称空间不是通过
包来完成的,而是通过散列的名称来完成的。唯一令人讨厌的是,你最终会写
$myProfile{color}
,而不是
$myProfile::color
。啊,谢谢-我没有想到我也可以在主模块上使用
BEGIN
,这很有帮助!