tags:

views:

274

answers:

4

As per subject: what are the characters that can be used in hash keys or, if it's shorter, which ones can't be used?

Also, are there any problems in using long hash keys (like full path names)?

+6  A: 

You can use any character that's valid in a string. Length isn't an issue either. Perl will cope with just about anything :)

dave
+5  A: 

You can use any character in a hash key --- a hash key is just a string. But for some characters you need to quote the string. If in doubt, just put quotes round the key.

$hash{simplekey}                             # fine
$hash{/var/log/auth.log}                     # syntax error --- can't use '/' directly
$hash{"/var/log/auth.log"}                   # quoted string, so can use any character
my $key = "/var/log/auth.log";  $hash{$key}  # variable used, which can contain any character

There's no special problem with using long keys that you don't already have with long strings.

Dave Hinton
+16  A: 

See How Hashes Really Work for a discussion on this topic. In short, as long as you quote the key (non-interpolating q{}), you can use whatever characters you want.

Regarding Dana's answer, no, it won't take longer for longer keys to get matched: it will take infinitesimally longer to hash the key, but that's all.

For reference, this is the hashing function in Perl 5.10.0:

#define PERL_HASH(hash,str,len)
 STMT_START {
    register const char * const s_PeRlHaSh_tmp = str;
    register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp;
    register I32 i_PeRlHaSh = len;
    register U32 hash_PeRlHaSh = PERL_HASH_SEED;
    while (i_PeRlHaSh--) {
        hash_PeRlHaSh += *s_PeRlHaSh++;
        hash_PeRlHaSh += (hash_PeRlHaSh << 10);
        hash_PeRlHaSh ^= (hash_PeRlHaSh >> 6);
    }
    hash_PeRlHaSh += (hash_PeRlHaSh << 3);
    hash_PeRlHaSh ^= (hash_PeRlHaSh >> 11);
    (hash) = (hash_PeRlHaSh + (hash_PeRlHaSh << 15));
} STMT_END
Pedro Silva
+5  A: 

One point not brought up yet is that you can use any valid string as a hash key. If you try to use something other than a string, it will be automatically stringified, which means that, e.g.,

my $ref = [];
$hash{$ref} = 'foo';

will use the string "ARRAY(0xdeadbeef)" (or whatever address) as the hash key, not the actual array reference.

Dave Sherohman
+1 for the address :)
kemp