Perl 编写反射方法从conf文件加载变量,并分配引用?

Perl 编写反射方法从conf文件加载变量,并分配引用?,perl,reference,configuration-files,Perl,Reference,Configuration Files,我正在处理难看的代码,并试图通过将模块中的值移动到配置文件中来进行清理。如果conf文件中不存在变量,我希望保留模块的默认值,否则使用conf文件版本。模块中有很多变量(太多),所以我想要一个助手方法来支持这一点。这是重构的第一步,稍后我可能会进一步更好地处理配置变量,但每次只执行一步 我想要一个方法,它在我的模块中接受一个变量,或者从conf加载值,或者设置一个默认值。类似这样的东西(从头开始编写,所以现在只将其视为伪代码) 这里有两个问题。首先,有人知道像我的load_var这样的功能是否已

我正在处理难看的代码,并试图通过将模块中的值移动到配置文件中来进行清理。如果conf文件中不存在变量,我希望保留模块的默认值,否则使用conf文件版本。模块中有很多变量(太多),所以我想要一个助手方法来支持这一点。这是重构的第一步,稍后我可能会进一步更好地处理配置变量,但每次只执行一步

我想要一个方法,它在我的模块中接受一个变量,或者从conf加载值,或者设置一个默认值。类似这样的东西(从头开始编写,所以现在只将其视为伪代码)

这里有两个问题。首先,有人知道像我的load_var这样的功能是否已经存在,我需要重用它吗


第二,如果我必须从头开始编写,那么我可以使用比5.22更旧的perl版本吗?当我读到perlref时,它提到设置引用是5.22中的一个新特性,但奇怪的是,引用的这种基本行为没有很快实现,所以我想知道我是否误解了文档。有没有一种方法可以将变量传递给我的load\u var方法并确保它实际得到更新?

对于这类问题,我会考虑使用-我知道这不是你所要求的,但它也做了类似的事情:

如果调用未定义的子例程,通常会出现一个立即的致命错误,抱怨该子例程不存在。(同样,对于用作方法的子例程,当该方法不存在于该类包的任何基类中时。)但是,如果在用于定位原始子例程的一个或多个包中定义了自动加载子例程,然后,自动加载子例程将使用传递给原始子例程的参数进行调用

比如:

#!/usr/bin/env perl

package Narf;
use Data::Dumper;
use strict;
use warnings;
our $AUTOLOAD;
my %conf = ( fish => 1, 
             carrot => "banana" ); 

sub AUTOLOAD { 
    print "Loading $AUTOLOAD\n";
    ##read config file
    my $target = $AUTOLOAD =~ s/.*:://gr; 
    print $target;
    return $conf{$target} // 0; 
}

sub boo {
    print "Boo!\n";
}
您可以将其称为OO样式,也可以仅称为“正常”-但请记住,这会创建sub,而不是变量,因此您可能需要指定包(或者“强制”导入/导出)


注意-由于这些是自动加载的,所以它们不在本地名称空间中。与你已经得到的变量相关,但我不认为这是一条好的路线,对于这类问题,出于

中概述的所有原因,我会考虑使用-我知道这不是你所要求的,但它做了类似的事情:

如果调用未定义的子例程,通常会出现一个立即的致命错误,抱怨该子例程不存在。(同样,对于用作方法的子例程,当该方法不存在于该类包的任何基类中时。)但是,如果在用于定位原始子例程的一个或多个包中定义了自动加载子例程,然后,自动加载子例程将使用传递给原始子例程的参数进行调用

比如:

#!/usr/bin/env perl

package Narf;
use Data::Dumper;
use strict;
use warnings;
our $AUTOLOAD;
my %conf = ( fish => 1, 
             carrot => "banana" ); 

sub AUTOLOAD { 
    print "Loading $AUTOLOAD\n";
    ##read config file
    my $target = $AUTOLOAD =~ s/.*:://gr; 
    print $target;
    return $conf{$target} // 0; 
}

sub boo {
    print "Boo!\n";
}
您可以将其称为OO样式,也可以仅称为“正常”-但请记住,这会创建sub,而不是变量,因此您可能需要指定包(或者“强制”导入/导出)


注意-由于这些是自动加载的,所以它们不在本地名称空间中。与你得到的变量相关,但我不认为这是一条好的路线,因为

\$var2=\$var1(为了别名两个变量而分配到引用),但是
my$ref=\$var$$ref=$val(分配给引用的标量以更改标量)很古老。我会采取稍微不同的方法:使用数据结构存储对每个变量的引用、其默认值以及配置哈希中对应键的名称。遍历结构并为引用指定适当的值。这样一来,变量的名称就不必与配置散列中的键匹配,而且你也不会做奇怪的“变量作为变量名”的事情。类似这样的内容:
my%defaults=(foo=>{ref=>\$foo,default=>“foo”},…)
这里,
foo
是配置哈希中的一个键,
$foo
是要“加载”的变量。@ThisSuitesBlack不是一个好的观点。然而,这里有一个操作顺序。在我的示例中,bar依赖于foo,必须首先定义foo才能正确定义bar。因此,在foo运行之前,我无法为bar定义“default”键。我想您不知道如何根据该要求保留默认哈希?(虽然对于记录,我认为我的load_var子例程将使用一个可选参数来覆盖配置文件变量的名称。我倾向于默认情况下保持不变,只是为了现在加快转换速度,同时不进行硬编码。当然,这是可行的。使用数组可以按固定顺序迭代并存储引用到“default”字段中的另一个变量,例如
my@defaults=({config=>'foo',ref=>\$foo,default=>“foo”},{config=>'bar',ref=>\$bar,default=>\$foo},…);
您必须检查默认值是否为引用,并进行相应的处理。此外,请记住,这种类型的东西只应作为权宜之计,以使进一步的重构更容易。最终,您应该从使用一大堆标量转向使用单个配置哈希。您提到过这一点吗根据此模块有多个脚本;一种方法是使用一堆标量和包含相同数据的散列。然后您可以将脚本逐个迁移到使用散列,当它们都不再使用标量时,将其从模块中删除。
\$var2=\$var1;
(为了别名两个变量而分配到引用)刚刚添加,但是
my$ref=\$var;$$ref=$val;
(为了更改而分配到引用的标量
#!/usr/bin/env perl
use strict;
use warnings;

use Narf;

print Narf::fish(),"\n";
print Narf::carrot(),"\n";
print Narf::somethingelse(),"\n";
print Narf::boo;