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 <eda@waniasset.com>Thread Previous | Thread Next