我的最愛是Config::Std。我喜歡它處理multi-line和multi-part配置值的方式。
當變量爲潛在的多值時,您必須小心:如果配置文件中存在單個值,則它將以標量存儲該值;如果存在多個值,您將獲得數組引用。
我覺得有兩個配置文件很方便:一個用於描述操作環境的值(在哪裏可以找到庫等),另一個用於用戶可修改的行爲。
我也想寫一個包裝它。例如(更新爲包括自動生成的只讀存取器):
#!/usr/bin/perl
package My::Config;
use strict; use warnings;
use Config::Std;
use FindBin qw($Bin);
use File::Spec::Functions qw(catfile);
sub new {
my $class = shift;
my ($config_file) = @_;
$config_file = catfile($Bin, 'config.ini');
read_config $config_file => my %config;
my $object = bless \%config => $class;
$object->gen_accessors(
single => {
install => [ qw(root) ],
},
multi => {
template => [ qw(dir) ],
},
);
return $object;
}
sub gen_accessors {
my $config = shift;
my %args = @_;
my $class = ref $config;
{
no strict 'refs';
for my $section (keys %{ $args{single} }) {
my @vars = @{ $args{single}->{$section} };
for my $var (@vars) {
*{ "${class}::${section}_${var}" } = sub {
$config->{$section}{$var};
};
}
}
for my $section (keys %{ $args{multi} }) {
my @vars = @{ $args{multi}->{$section} };
for my $var (@vars) {
*{ "${class}::${section}_${var}" } = sub {
my $val = $config->{$section}{$var};
return [ $val ] unless 'ARRAY' eq ref $val;
return $val;
}
}
}
}
return;
}
package main;
use strict; use warnings;
my $config = My::Config->new;
use Data::Dumper;
print Dumper($config->install_root, $config->template_dir);
C:\Temp> cat config.ini
[install]
root = c:\opt
[template]
dir = C:\opt\app\tmpl
dir = C:\opt\common\tmpl
輸出:
C:\Temp> g.pl
$VAR1 = 'c:\\opt';
$VAR2 = [
'C:\\opt\\app\\tmpl',
'C:\\opt\\common\\tmpl'
];
+1非常有幫助 - 謝謝。好像應該有一個模塊可以爲我們生成'template_dirs'這樣的方法。我偶然發現了'Config :: General',特別是它的'-ExtendedAccess'選項。從未使用過它,但它看起來很有趣。 – FMc
@FM我不知道「Config :: General」。它確實看起來很有趣,但我發現有時一般的解決方案可能有點過於籠統。當然,可以自動爲標量值選項自動生成訪問器,並分別爲潛在的多值選項自動生成訪問器。 –