develooper Front page | perl.beginners | Postings from August 2009

Re: Inverting a hash safely

Thread Previous | Thread Next
Ed Avis
August 3, 2009 14:31
Re: Inverting a hash safely
Message ID:
Jenda Krynicky <Jenda <at>> writes:

>>     my %hash = (a => 1, b => 2);
>>     my %reverse = safe_hash_invert %hash; # works fine
>>     $hash{c} = 1;
>>     %reverse = safe_hash_invert %hash; # throws an error 

>I don't think there is and I don't think there's a need.
>my %hash = (a => 1, b => 2,
> c => 1,
>my %reverse = reverse %hash;
>die "Bummer, the values were not unique!"
> if keys(%hash) != keys(%reverse);

Of course this works.  But even at three lines of code it's still worth making
into a function.  The 'any' and 'none' functions in List::MoreUtils are even
more trivial but it's still very handy to have them.

To give a really useful error message is a bit more code:

    my %reverse;
    foreach my $k (sort keys %hash) {
        my $v = $hash{$k};
        if (exists $reverse{$k}) {
            die "cannot reverse: $v is mapped to by both $k and $reverse{$k}\n";
        $reverse{$k} = $v;

However, even if it's just one extra line of code as you suggest, that still
makes it temptingly easy to just forget the check.  I did so myself, and while
I am no Don Knuth, I'm more conscientious than some people I know!  So if I
can forget to check it so can many others.

So one reason to have a function providing this is to give a simple FAQ entry
on reversing a hash: 'just use Whatever::Module::safe_hash_invert'.  And, for
those who like that kind of thing, a simple way to audit existing code for
bugs (or latent bugs) caused by hash reversing without checking; I would ideally
provide both safe_hash_invert and unsafe_hash_invert so that the programmer can
be explicit about what's intended.

Anyway, I think I will send a patch to Hash::MoreUtils if some module doesn't
already provide this code.

Ed Avis <>

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About