我使用了我在Reading and Writing Perl Config Files上找到的PerlMonk示例
Configuration.pl:
%CFG = (
'servers' => {
'SRV1' => {
'IP' => 99.32.4.0,
'user' => 'aname',
'pswd' => 'p4ssw0rd',
'status' => 'unavailable'
},
'SRV2' => {
'IP' => 129.99.10.5
'user' => 'guest',
'pswd' => 'guest'
'status' => 'unavailable'
}
},
'timeout' => 60,
'log' => {
'file' => '/var/log/my_log.log',
'level' => 'warn',
},
'temp' => 'remove me'
);它工作得很好,但唯一的问题是当读写像配置一样的散列时是“乱序”的。有没有办法让它保持平局?
这一点很重要,因为配置文件也是手动编辑的,所以我希望键和值的顺序相同。
发布于 2013-06-07 00:34:30
如果您使用JSON,那么您的软件就不会受到恶意攻击(或意外损坏),这是您的优势。JSON还具有比Perl数据结构更简单的语法,并且更容易从语法错误中恢复。
设置Perl选项将创建具有排序顺序的键的数据,因此每次都会为相同的canonical数据生成相同的输出。如果您需要按特定顺序而不是字母顺序排列数据,则可以使用Tie::IxHash模块,正如@mpapec在他的回答中所描述的那样。
或者,您可以使用该模块的Pure Perl版本中的sort_by方法,它允许您传递一个排列子例程。这将允许您规定键的顺序,并且可以像使用散列一样简单,该散列将所有可能的键值与数字排序顺序相关联。
该程序使用sort_by方法按照键在原始散列中出现的顺序重新构建JSON。这不太可能是您想要的顺序,但机制是存在的。它的工作原理是在哈希表中查找每个键,以确定它们应该如何排序。默认情况下,没有出现在散列中的任何键(如这里的SVR1和SVR2 )都按字母顺序排序。
use strict;
use warnings;
use JSON::PP ();
my %CFG = (
'servers' => {
'SRV1' => {
'IP' => '99.32.4.0',
'user' => 'aname',
'pswd' => 'p4ssw0rd',
'status' => 'unavailable'
},
'SRV2' => {
'IP' => '129.99.10.5',
'user' => 'guest',
'pswd' => 'guest',
'status' => 'unavailable'
}
},
'timeout' => 60,
'log' => {
'file' => '/var/log/my_log.log',
'level' => 'warn',
},
'temp' => 'remove me'
);
my %sort_order;
my $n = 0;
$sort_order{$_} = ++$n for qw/ servers timeout log temp /;
$sort_order{$_} = ++$n for qw/ IP user pswd status /;
$sort_order{$_} = ++$n for qw/ file level /;
my $json = JSON::PP->new->pretty->sort_by(\&json_sort);
print $json->encode(\%CFG);
sub json_sort {
my ($aa, $bb) = map $sort_order{$_}, $JSON::PP::a, $JSON::PP::b;
$aa and $bb and $aa <=> $bb or $JSON::PP::a cmp $JSON::PP::b;
}生成此输出
{
"servers" : {
"SRV1" : {
"IP" : "99.32.4.0",
"user" : "aname",
"pswd" : "p4ssw0rd",
"status" : "unavailable"
},
"SRV2" : {
"IP" : "129.99.10.5",
"user" : "guest",
"pswd" : "guest",
"status" : "unavailable"
}
},
"timeout" : 60,
"log" : {
"file" : "/var/log/my_log.log",
"level" : "warn"
},
"temp" : "remove me"
}可以简单地将其保存到文件并类似地恢复。
发布于 2013-06-06 22:48:56
您可以在使用配置变量之前对其执行tie操作,这样以后哈希键将保持与以前相同的顺序,
use strict;
use warnings;
use Tie::IxHash;
tie my %CFG, 'Tie::IxHash';
%CFG = (
'servers' => {
'SRV1' => {
'IP' => '99.32.4.0',
'user' => 'aname',
'pswd' => 'p4ssw0rd',
'status' => 'unavailable'
},
'SRV2' => {
'IP' => '129.99.10.5',
'user' => 'guest',
'pswd' => 'guest',
'status' => 'unavailable'
}
},
'timeout' => 60,
'log' => {
'file' => '/var/log/my_log.log',
'level' => 'warn',
},
'temp' => 'remove me'
);
use Data::Dumper;
print Dumper \%CFG;https://stackoverflow.com/questions/16964210
复制相似问题