字符串化哈希时Data :: Dumper的一致性

时间:2015-03-20 08:04:47

标签: perl hash perl-data-structures

我正在从配置文件中重复加载一系列哈希(用JSON编写),然后确保它们都没有更改。

所以,如果配置文件是这样的:

  "sources" : [
    {
      "source_name": "A",
      "interval"   : 6,
      "params"     : {
        "what" : "testA"
      }
    },
    {
      "source_name": "B",
      "interval"   : 6,
      "params"     : {
        "what" : "testB"
      }
    }
  ]

然后在下一次运行中它改为此(只交换前两行,实际上没有任何改变):

  "sources" : [
    {
      "interval"   : 6,
      "source_name": "A",
      "params"     : {
        "what" : "testA"
      }
    },
    {
      "source_name": "B",
      "interval"   : 6,
      "params"     : {
        "what" : "testB"
      }
    }
  ]

我应该能够发现没有任何改变。

出于这个原因,我可能Digest::SHA哈希的字符串化。那么,问题是Data::Dumper是否一致?就像,如果我传递两个相同的哈希值,我总是会得到一个相同的字符串吗?我已经尝试改变按键的顺序了,看起来一致;但当然这不是证据。

如果没有,有关如何做的任何建议吗?

3 个答案:

答案 0 :(得分:2)

我相信你应该使用Data::Compare

  

那么,问题是,Data :: Dumper是否一致?就像,如果我传递两个相同的哈希值,我总是会得到一个相同的字符串吗?

哈希不是订购的,所以我不会依赖它,但如果你想要的话,你可以在打印之前进行排序。

答案 1 :(得分:1)

您可以使用$Data::Dumper::Sortkeys = 1;确保在转出时对密钥进行排序;

use Data::Dumper;

$Data::Dumper::Sortkeys = 1;
my $hash = {b => 2, a => 1, };
print Dumper $hash; 

如果要比较两个哈希是否具有相同的结构,可以使用Test::Deep::NoTest

use Test::Deep::NoTest;

my $hash_1 = {a => 1, b => 2 };
my $hash_2 = {b => 2, a => 1 };
if(eq_deeply($hash_1, $hash_2)){
    println "same!\n";
}

答案 2 :(得分:0)

  

Data :: Dumper是否一致?

除非你告诉它,否则不是。您可以通过设置Sortkeys来完成此操作。

my $dumper = Data::Dumper->new( $data );
$dumper->Sortkeys(1);
print $dumper->Dump;

这是因为哈希没有固有的顺序。在旧版本的Perl中,具有相同键集的哈希顺序将保持一致,但这不再可靠。

或者,您可以使用perl5i及其diff方法。

use perl5i::2;

my $a = { foo => "bar" };
my $b = { foo => "barr" };

my $diff = $a->diff($b);
if( keys %$diff ) {
    say "There are differences.";
    say $diff->mo->as_json;
}
else {
    say "No differences.";
}

或使用perl5i's meta object checksum方法。

use perl5i::2;
say "No differences" if $a->mo->checksum eq $b->mo->checksum;