众所周知如何迭代perl中的哈希(例如,参见Perl哈希键的最安全的迭代方法是什么?).但是,键和值的顺序是不确定的,实际上每个perl脚本的运行都是不同的.
有没有办法确保相同输入数据上的相同perl脚本的每次运行都会产生相同的迭代顺序?我只关心这种意义上的可复制性 - 秩序不需要被人类预测.
编辑:我在迭代方面提出了问题,但也许它不是哈希的迭代,而是哈希构建过程是非确定性的.我可以设置一些初始化来以确定性和可复制的方式构建哈希吗?
sort
他们先:
foreach my $key ( sort keys %hash ) { }
注意:默认排序是按字母顺序排列,而不是数字.但是sort
会采用自定义功能,允许您按照您想要命名的任何顺序进行排序.
或者,捕获数组中的排序并使用它来提取输出顺序.
my %content_for; my @ordered_id; while ( <$input_filehandle> ) { my ( $id, $content ) = split; push ( @ordered_id, $id ); $content_for{$id} = $content; } print join ( "\n", @content_for{@ordered_id} ),"\n"
;
或像一个有序的散列机制类似Hash::Ordered
或Tie::IxHash
.
我在迭代方面提出了这个问题,但也许它不是对哈希的迭代,而是哈希构建过程是非确定性的.我可以设置一些初始化来以确定性和可复制的方式构建哈希吗?
不,哈希不像那样工作.请参阅 - perlsec
了解原因.随着更新版本的perl,它变得越来越随机,但它总是一个无序的数据结构.
你也许可以搞乱(如文章中提到的)PERL_HASH_SEED和PERL_PERTURB_KEYS,但这绝对不是一个好习惯.
PERL_HASH_SEED=0 ./somescript.pl
但是你应该记住,哈希排序仍然无法保证 - 密钥的排序可能仍会改变.尽管如此,它会比以前更加一致.这绝对不是在生产中使用的好东西,或者仅仅依赖于调试.
请注意:哈希种子是敏感信息.哈希是随机的,以防止针对Perl代码的本地和远程攻击.通过手动设置种子,可以部分或完全丧失这种保护.