読者です 読者をやめる 読者になる 読者になる

perl-5.18のhash randomizationについて

perl-5.18.0がリリースされました。

大きな変更点としてhash randomization(ハッシュのランダム化)が挙げられます。each(), keys(), values()の出力結果がランダムになるというものです。ちなみにprint %hash;したときもランダムになります。これによってテストがこけると言われていますが、ただテストがこけるだけなのか、そうではないとかというのが疑問だと思います。
実際にはほとんど問題ありません(テストがこけるだけかもしれません)。しかし、(ときどき)動かなくなるものも存在します。気をつけるポイントはひとつです。ハッシュはできる限りsortしてから扱うことです。

実例

Test::Difflet::is_deeply()にはhash randomizationに関するバグがありました。Data-Difflet-0.08ではすでにfixされています。

  • Data::Dumperの出力結果を比較することでデータ構造の比較を実現している
  • hash randomizationによってData::Dumperの出力結果がランダムになった
    • 配慮しているつもりだったが、SortkeysとするところをSortKeysとしていた
--- a/lib/Test/Difflet.pm
+++ b/lib/Test/Difflet.pm
@@ -41,7 +41,7 @@ sub _eq_deeply {
     my ($a, $b) = @_;
     local $Data::Dumper::Terse = 1;
     local $Data::Dumper::Indent = 0;
-    local $Data::Dumper::SortKeys = 1;
+    local $Data::Dumper::Sortkeys = 1;
     return Dumper($a) eq Dumper($b);
 }


蛇足ですが、Data::Dumperの出力がランダムになったのでデバッグするときにData::Dumperを使ってるんだよねーといった人は戸惑うかもしれません。
local $Data::Dumper::Sortkeys = 1;しておくようなsnippetを書いておくと捗りそうです。

snippet dumper
    use Data::Dumper; local $Data::Dumper::Sortkeys = 1; warn Dumper(${1:code});