Jenda Krynicky <Jenda <at> Krynicky.cz> 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 <e...@waniasset.com>





-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to