Perl - 使用Config :: General从conf文件创建数组的哈希

时间:2014-08-14 16:48:29

标签: perl

我使用Config :: General从包含以下格式数据的conf文件中读取:

<hash>
    <array1>
        val1
        val2
    </array1>
    <array2>
        val1
        val2
    </array2>
</hash>

虽然可以将数组值作为哈希键访问,但它并不是一个特别优雅的解决方案。

for my $array (keys $config{'hash'}) {
    for my $value (keys $config{'hash'}{$array}) {
      #do stuff
    }
}

有没有一种方法可以更改数据作为数组的哈希值进行正确访问,而不是采用这种方法有点像黑客?以下是我正在寻找的结果:

%hash = (
    array1 => [ 'value1', 'value2' ],
    array2 => [ 'value1', 'value2' ]
);

3 个答案:

答案 0 :(得分:3)

Config::General适用于键/值对。您的配置文件不包含键/值对,因此Config::General会将val1val2视为键,并为其指定值undef。结果数据结构如下所示:

{ 
  hash => {
    array1 => { val1 => undef, val2 => undef },
    array2 => { val1 => undef, val2 => undef },
  },
}

如果你的配置文件格式是固定的,你别无选择,只能自己破解结果数据结构。你是(ab)使用Config::General来获取它不适合的东西。

如果将文件格式更改为以下内容,则可以创建数组:

foo.cfg

<hash>
    array1 val1
    array1 val2
    array2 val1
    array2 val2
</hash>

use strict;
use warnings;

use Config::General;
use Data::Dump;

my $conf = Config::General->new(
    -ConfigFile => 'foo.cfg'
);
my %config = $conf->getall;

dd \%config;

输出

{ 
  hash => { array1 => ["val1", "val2"], array2 => ["val1", "val2"] },
}

答案 1 :(得分:3)

Config::General旨在使用键值对。它没有提供指定像您尝试的列表的方法。

虽然可以做的一件事是为同一个键提供多个键/值对,然后将它们合并到一个数组中。

use strict;
use warnings;

use Config::General;

my $conf = Config::General->new(
    -String      => do {local $/; <DATA>},
);
my %config = $conf->getall;

use Data::Dump;
dd \%config;

__DATA__
<hash>
    array1 = val1
    array1 = val2
    array2 = val1
    array2 = val2
</hash>

输出:

{
  hash => { array1 => ["val1", "val2"], array2 => ["val1", "val2"] },
}

此方法的唯一问题是在使用之前必须添加逻辑以确定键是数组引用还是标量。例如,以下是如何创建自己的循环来完成此配置:

for my $block (keys %config) {
    for my $key (keys %{$config{$block}}) {
        if (ref $config{$block}{$key}) {
            print "$block -> $key -> @{$config{$block}{$key}}\n";
        } else {
            print "$block -> $key -> $config{$block}{$key}\n";
        }
    }
}

输出:

hash -> array1 -> val1 val2
hash -> array2 -> val1 val2

使用YAML

的备选方案

如果您想要一个支持数组的人类可读配置文件,我建议您查看YAML

以下是您的配置文件以YAML格式重做,加载到数组哈希中,然后使用Data::Dump输出:

use strict;
use warnings;

use YAML;

my $conf = Load(do {local $/; <DATA>});

use Data::Dump;
dd $conf;

__DATA__
hash:
  array1:
    - val1
    - val2
  array2:
    - val1
    - val2
  array3:
    - val1

输出:

{
  hash => {
    array1 => ["val1", "val2"],
    array2 => ["val1", "val2"],
    array3 => ["val1"],
  },
}

答案 2 :(得分:0)

注意!!!如果你设置

        my $conf = new Config::General(
            -ConfigFile            => $config_file,
            -MergeDuplicateOptions => 1
    );   

上面的解决方案不起作用!