0

As part of migration from perl 5.8 to perl 5.30, unable to get the perl nested hash in sorted fashion. Tried disabling the hash randomization features in 5.30 (set PERL_PERTURB_KEYS=0 set PERL_HASH_SEED=0x00), but still the sorting doesn't apply to multi-level /nested hash.

Apart from sorting the foreach-keys in the perl code, is there any other way, like disabling any environment variables/configuration , so as to get the values in sorted fashion wrt to perl 5.30. Tried using the deprecated Deep:Hash::Util (nested hash sort of perl5.6) also, but did not work wrt to nested/mulit-level hash.

Ex: not-working:

$VAR3 = 'Mapping_1';
$VAR4 = {
'2' => {
        'ShortName' => 'Mapping_Tx2',
        'FileName' => 'Appl_1.arxml',
       
      },
'1' => {
        'ShortName' => 'Mapping_Tx1',
        'FileName' => 'Appl_1.arxml',
        
      }
};

working:

$VAR3 = 'Mapping_1';
$VAR4 = {
    '1' => {
        'ShortName' => 'Mapping_Tx1',
        'FileName' => 'Appl_1.arxml',
        
      },
'2' => {
        'ShortName' => 'Mapping_Tx2',
        'FileName' => 'Appl_1.arxml',
       
      }

};
  • 3
    Why would you need to store the sorted keys in a hash? What is the benefit compared to just storing them in an array? Give an example of how this is making your code "not work." – TLP Mar 17 '22 at 13:54
  • 2
    The same question is also being discussed on Reddit: https://www.reddit.com/r/perl/comments/tgazbq/unable_to_sort_a_multilevel_hash_nested_hash_in/ – amon Mar 17 '22 at 14:21

1 Answers1

4

Perl's hashes are not and were not ordered. If your code relied on particular orderings in Perl 5.8, it was probably buggy and only worked by accident.

You have two reasonable options here.

  1. You can stop trying to make the data structure itself keep a particular order, and instead choose an order when you use the data structure. For example, to iterate over all hash keys in a stable order you might use for (sort keys %hash) instead of for (keys %hash). This is almost always the correct approach.

  2. Use a different data structure that maintains order. If you need a stable ordering but do not need fast key→value access, consider an array. Otherwise, consider creating a class that implements the data structure you need, probably by using a hash internally and also an array to store the order. Which approach to choose depends on the particular order you want. For example, Hash::Ordered maintains the insertion order.

amon
  • 57,091
  • 2
  • 89
  • 149
  • 1
    [Example of lack of order of hashes in 5.8.9](https://gist.github.com/ikegami/72cad81173d6a9c5e49319d7899d4036) – ikegami Mar 17 '22 at 23:59