tags:

views:

1190

answers:

3

Evidently hash keys are compared in a case-sensitive manner.

$ perl -e '%hash = ( FOO => 1 ); printf "%s\n", ( exists $hash{foo} ) ? "Yes" : "No";'
No

$ perl -e '%hash = ( FOO => 1 ); printf "%s\n", ( exists $hash{FOO} ) ? "Yes" : "No";'
Yes

Is there a setting to change that for the current script?

Thanks.

+6  A: 

The hash of a string and the same string with the case changed are not equal. So you can't do what you want, short of calling "uc" on every hash key before you create it AND before you use it.

Paul Tomblin
+10  A: 

You will have to use a tied hash. For example Hash::Case::Preserve.

Leon Timmermans
I wonder what the speed and space penalties there are for this implementation versus just making sure people get their hash keys in the right case in the first place?
Paul Tomblin
I shouldn't cost much in space, though it will definitely cost in time. Having said that, in most cases it won't matter much IMHO.
Leon Timmermans
+1  A: 
my %hash = (FOO => 1);
my $key = 'fOo'; # or 'foo' for that matter

my %lookup = map {(lc $_, $hash{$_})} keys %hash;
printf "%s\n", ( exists $hash{(lc $key)} ) ? "Yes" : "No";
amphetamachine
I like where you're going with this, but when I run it in ActiveState Perl on Win32, I get "No".I think you meant:( exists $lookup{(lc $key)} ) ? "Yes" : "No"
mseery