We needed to have hashes where values could be found in the hash, even if a key was used that had a different case than the original key used to put the value into the hash. So, I investigated tied hashes in Perl, and soon developed a library to do just that, which seemed to work fine, until recently, when I found that sometimes my hash objects acted as though they were empty, when clearly they were not. In fact, I ran into this strange situation:
# --- $hTied exists and is a tied hash foreach my $key (keys(%$hTied)) { print("$key = $hTied->{$key}\n"); } # --- the above prints nothing, as if the hash %$hTied has no keys, but my $h2 = $hTied->{prod1}; foreach my $key (keys(%$hTied)) { print("$key = $hTied->{$key}\n"); } # --- the above prints out several keys and values # --- i.e. it looks like $hTied is empty, but $hTied->{prod1}exists and contains data I eventually tracked the problem down to the fact that my tied hash contained an entry with an undef key. Normal hashes in Perl not only allow that, but work perfectly. The entry with the undef key can be retrieved like any other key: my $h = { a => 1, undef , 2, c => 3, }; foreach my $key (keys(%$h)) { print("'$key' => '$h->{$key}'\n"); } prints out: '' => '2' 'c' => '3' 'a' => '1' (but note that I couldn't say undef => 2 because the magic of => would cause it to treat undef as the string 'undef'. Also, my printing routine doesn't distinguish between keys that are undef and keys that are the empty string, but I could remedy that by making the foreach loop a bit more complex by checking to see if $key is defined or not) So, understanding the problem, I figured that I'd go into my library and simply fix the problem. So, I looked at my FIRSTKEY function. What it is supposed to do is to retrieve the first key, and the first value and return the first key in scalar context, or the pair first key and first value if in list context. If there are no keys in the hash, it's supposed to return undef in scalar context, but the empty list if in array context. Well, we've got a serious logical problem if the first key in the hash is undef - since returning undef in scalar context is how we're supposed to indicate that there are no keys. Also, I should mention that I found 2 other Perl libraries that are supposed to do the same thing, i.e. have case insensitive retrieval of values from a hash while retaining the original case of the keys. These are Tie::CPHash and Hash::Case::Preserve. I found that both of these libraries also have the same problem with undef keys. The solution I'm going to use in my library is to convert undef keys to the empty string - probably on insert, but it would also work to return the empty string for undef keys found in the FIRSTKEY and NEXTKEY functions. It's a bit annoying that with tied hashes, it seems to be impossible to emulate the behavior of real Perl hashes with respect to undef keys. If anyone knows of a way around this problem that would allow tied hashes to work just like true Perl hashes, except that lookups would be case-insensitive. Also, if anyone knows of a library implemented in C code, which would be much faster than any of the libraries mentioned, that did this, I'd appreciate knowing about it. A google search didn't turn up any such library. _______________________________________________ Perl-Win32-Users mailing list Perl-Win32-Users@listserv.ActiveState.com To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs