in reply to Tie one hash two ways?

Do you need to preserve the case of the keys? It might be easiest to convert all keys to lowercase in the hash and then lowercase the keys whenever you do any lookup.

If you do have to keep the case you might create a lookup hash that would just map from the lowercased keys to the original ones and then do a two-step lookup:

my %alt_seqindex; $alt_seqindex{lc $key} = $key while (my ($key) = each %seqindex);
and then do the case insensitive lookup like this:
$value = $seqindex{$alt_seqindex{lc $key}};
If you do want to hide this from the users you may subclass BerkeleyDB::Hash, somewhat like this:
package BerkeleyDB::Hash::CasePreserve; use BerkeleyDB; use base 'BerkeleyDB::Hash'; my %LCKeys; # to keep the lc $key => $key mapping for all hashes sub TIEHASH { my $obj = &BerkeleyDB::Hash::TIEHASH; my %lckeys; my $key = $obj->FIRSTKEY(); $lckeys{lc $key} = $key; $lckeys{lc $key} = $key while $key = $obj->NEXTKEY($key); $LCKeys{$obj->[0]} = \%lckeys; return $obj; } sub FETCH { my $self = shift; my $key = shift(); $key = $LCKeys{$self->[0]}->{lc $key} or return; return $self->SUPER::FETCH($key); } sub EXISTS { my $self = shift; my $key = shift(); $key = $LCKeys{$self->[0]}->{lc $key} or return; return $self->SUPER::EXISTS($key); } sub STORE { my $self = shift; my ($key, $value) = @_; if (exists $LCKeys{$self->[0]}->{lc $key}) { $key = $LCKeys{$self->[0]}->{lc $key}; } else { $LCKeys{$self->[0]}->{lc $key} = $key; } return $self->SUPER::STORE($key, $value); } sub DESTROY { my $self = shift(); delete $LCKeys{$self->[0]}; } 1;
This implementation will be much quicker than Fletch's since it doesn't search through the whole tied hash each and every time.

Jenda
Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
   -- Rick Osborne