编写反射方法从 conf 文件加载变量,并分配引用?
writing reflective method to load variables from conf file, and assigning references?
我正在处理丑陋的代码,并试图通过将模块中的值移动到配置文件中来进行清理。如果 conf 文件中不存在变量,我想保留模块默认值,否则使用 conf 文件版本。模块中有很多变量(太多)所以我想要一个辅助方法来支持它。这是重构的第一步,我可能会在以后进一步处理配置变量,但一次一个步骤。
我想要一种方法,它可以在我的模块中获取一个变量,然后从 conf 加载值或设置默认值。所以像这样(从头开始写,所以现在把它当作伪代码)
Our ($var_a, $var_b ...);
export($var_a, $var_b ...);
my %conf = #load config file
load_var($var_a, "foo");
load_var($var_b, "$var_abar");
sub load_var($$){
my($variable_ref, $default) = @_
my $variale_name = Dumper($$variable_ref); #get name of variable
my $variable_value = $conf{$variable_name} // $default;
#update original variable by having $variable_ref point to $variable_value
}
这里有两个问题。首先,有谁知道像我的 load_var 这样的功能是否已经存在,我可以重用?
其次,如果我必须从头开始编写,我可以使用早于 5.22 的 perl 版本来完成吗?当我阅读 perlref 时,它指的是将引用设置为 5.22 中的一项新功能,但奇怪的是,这种引用的基本行为没有早点实现,所以我想知道我是否误解了文档。有没有办法将变量传递给我的 load_var 方法并确保它实际更新?
对于这类问题,我会考虑使用 AUTOLOAD - 我知道这与您的要求不完全相同,但它在做类似的事情:
If you call a subroutine that is undefined, you would ordinarily get an immediate, fatal error complaining that the subroutine doesn't exist. (Likewise for subroutines being used as methods, when the method doesn't exist in any base class of the class's package.) However, if an AUTOLOAD subroutine is defined in the package or packages used to locate the original subroutine, then that AUTOLOAD subroutine is called with the arguments that would have been passed to the original subroutine.
类似于:
#!/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 风格,或者只是 'normally' - 但请记住,这会创建子程序,而不是变量,因此您可能需要指定包(或者 'force' import/export)
#!/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;
注意 - 由于这些是自动加载的,因此它们不在本地命名空间中。与您获得的变量相关 this perlmonks discussion but I'm not convinced that's a good line to take, for all the reasons outlined in Why it's stupid to `use a variable as a variable name'
我正在处理丑陋的代码,并试图通过将模块中的值移动到配置文件中来进行清理。如果 conf 文件中不存在变量,我想保留模块默认值,否则使用 conf 文件版本。模块中有很多变量(太多)所以我想要一个辅助方法来支持它。这是重构的第一步,我可能会在以后进一步处理配置变量,但一次一个步骤。
我想要一种方法,它可以在我的模块中获取一个变量,然后从 conf 加载值或设置默认值。所以像这样(从头开始写,所以现在把它当作伪代码)
Our ($var_a, $var_b ...);
export($var_a, $var_b ...);
my %conf = #load config file
load_var($var_a, "foo");
load_var($var_b, "$var_abar");
sub load_var($$){
my($variable_ref, $default) = @_
my $variale_name = Dumper($$variable_ref); #get name of variable
my $variable_value = $conf{$variable_name} // $default;
#update original variable by having $variable_ref point to $variable_value
}
这里有两个问题。首先,有谁知道像我的 load_var 这样的功能是否已经存在,我可以重用?
其次,如果我必须从头开始编写,我可以使用早于 5.22 的 perl 版本来完成吗?当我阅读 perlref 时,它指的是将引用设置为 5.22 中的一项新功能,但奇怪的是,这种引用的基本行为没有早点实现,所以我想知道我是否误解了文档。有没有办法将变量传递给我的 load_var 方法并确保它实际更新?
对于这类问题,我会考虑使用 AUTOLOAD - 我知道这与您的要求不完全相同,但它在做类似的事情:
If you call a subroutine that is undefined, you would ordinarily get an immediate, fatal error complaining that the subroutine doesn't exist. (Likewise for subroutines being used as methods, when the method doesn't exist in any base class of the class's package.) However, if an AUTOLOAD subroutine is defined in the package or packages used to locate the original subroutine, then that AUTOLOAD subroutine is called with the arguments that would have been passed to the original subroutine.
类似于:
#!/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 风格,或者只是 'normally' - 但请记住,这会创建子程序,而不是变量,因此您可能需要指定包(或者 'force' import/export)
#!/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;
注意 - 由于这些是自动加载的,因此它们不在本地命名空间中。与您获得的变量相关 this perlmonks discussion but I'm not convinced that's a good line to take, for all the reasons outlined in Why it's stupid to `use a variable as a variable name'