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 <[email protected]>
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
http://learn.perl.org/