Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Is it possible to "fix a seed" for hash?

by rsFalse (Chaplain)
on Mar 16, 2021 at 12:57 UTC ( #11129756=perlquestion: print w/replies, xml ) Need Help??

rsFalse has asked for the wisdom of the Perl Monks concerning the following question:

Hello,

Is it possible to set fixed hash behavior: getting the same order of keys (or values, or each)?
1. For every same hash in running script.
2. For every same hash between running script several times.

How scripts, output of which depend on hashes, are tested? E.g. once generated desired output, which is suitable for being a test case, won't be the same in the next run?

Comparing to scripts which uses 'rand' one can set the same seed ('srand CONST') for getting the same output every time.

Upd. E.g. I shuffled (10k times) an array with a hash, and got different patterns of shuffling occurrences between different script runs (see from here: Re: RFC: Kinda pseudo-shuffle using sort).

Replies are listed 'Best First'.
Re: Is it possible to "fix a seed" for hash?
by choroba (Archbishop) on Mar 16, 2021 at 13:01 UTC
    See PERL_HASH_SEED and other related variables in perlrun.

    Scripts whose output depends on hashes are tested wrongly, because such scripts are buggy. If the order is important, sort the values, if it's not, use bag from Test::Deep in the tests.

    Update: Similarly, for Test2 based testing, see Bag Builder in Test2::Tools::Compare.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      I tried to set PERL_HASH_SEED to 0, but I'm getting different outputs each time.
        I tried to set PERL_HASH_SEED to 0, but I'm getting different outputs each time.

        As choroba said, there are "other related variables" too, e.g. PERL_PERTURB_KEYS.

        However, since from your reply it seems like you're continuing down this route, let me state what I said here more directly: I can say with near certainty that you shouldn't be messing with these variables in the first place! Unless you can explain with certainty why you think you need these variables, I am certain we will be able to find a better (more robust, more portable, etc.) solution for you. So please explain your application some more, and the issue you are experiencing, and let's find a better solution than messing with PERL_HASH_SEED.

        Update: Rereading the node, that's a lot of certainty ;-)

        $ for i in {1..1000} ; do PERL_HASH_SEED=0 perl -lwe '%x = qw(a b c d +e f); print %x' ; done | sort | uniq -c 1000 cdefab
        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: Is it possible to "fix a seed" for hash?
by haukex (Archbishop) on Mar 16, 2021 at 14:57 UTC
    Is it possible to set fixed hash behavior: getting the same order of keys (or values, or each)?

    IMHO, 99.9% of the time, this is an XY Problem. Maybe something like 80% of the time, the correct answers are "sort the keys of the hash on output", "use an array", or less often, "use a module like Tie::IxHash". See also the FAQ How do I sort a hash (optionally by value instead of key)? and the following question.

    Even if you set PERL_HASH_SEED and the related variables, Perl makes no guarantees that this will stay stable across Perl versions. Hashes are always unordered.

    How scripts, output of which depend on hashes, are tested?

    By sorting the keys of the hash on output (see also Data::Dumper's Sortkeys, Data::Dump, most JSON modules have the canonical option, etc.), or if testing the contents of the hash directly, comparison functions like is_deeply from Test::More or Compare from Data::Compare don't care about hash order (since there is none).

Re: Is it possible to "fix a seed" for hash?
by Anonymous Monk on Mar 16, 2021 at 13:02 UTC
A reply falls below the community's threshold of quality. You may see it by logging in.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11129756]
Approved by marto
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (2)
As of 2022-08-14 14:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?