Hash key types and equality of hash keys

Discussion in 'Perl Misc' started by Tim McDaniel, Mar 1, 2012.

  1. Tim McDaniel

    Tim McDaniel Guest

    I tried "man perldata", but I didn't notice anything applicable.

    I've always used only strings as hash keys -- I've just assumed
    without any evidence that they're the only things that work.
    But it occurred to me to wonder what else could be used as keys.
    (Any scalar value can be used as hash *data*, I think.)
    I was expecting errors from

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    #! /usr/bin/perl
    use warnings;
    use strict;
    use Data::Dumper;
    my %hash = ();
    my $i = 23;
    $hash{\$i} = 'narf';
    $hash{sub { print 'blort' }} = 'hurple';
    my $f = sub { print 'bazinga' };
    $hash{$f} = 'poit';
    $hash{qr/acc/} = 'zing';
    $hash{undef} = 'WTF?';
    print $hash{\$i}, "\n";
    print $hash{sub { print 'blort' }}, "\n";
    print $hash{$f}, "\n";
    print $hash{qr/acc/}, "\n";
    print $hash{undef}, "\n";
    print Data::Dumper->Dump([\%hash], [qw[hash]]), "\n";
    exit 0;

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    but I was astonished that most of it worked:

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    $ perl ~/local/test/027.pl ; perl -v
    narf
    Use of uninitialized value in print at
    /home/tmcdaniel/local/test/027.pl line 14.

    poit
    zing
    WTF?
    $hash = {
    'SCALAR(0x116ede20)' => 'narf',
    'undef' => 'WTF?',
    'CODE(0x116f4200)' => 'poit',
    'CODE(0x116ede80)' => 'hurple',
    '(?-xism:acc)' => 'zing'
    };

    This is perl, v5.8.8 built for x86_64-linux-thread-multi
    ....

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    So I'm thinking that, in Perl, hash keys can also be any scalar.
    Is that documented anywhere?

    That then leads to the question: what counts as "equal" in the context
    of looking up a hash value?

    - sub { print 'blort' } is considered a different key from a later
    lexical use of sub { print 'blort' }.

    - But qr/acc/ matches a later lexical use of qr/acc/.

    - The same reference to the same item is equal to itself, which is not
    surprising. That is, evaluate the reference in one place, store it
    in a variable, and use that variable's value. (E.g., $f = sub {...}
    and use $f.)

    - A reference to the same scalar (\$i) is consistent, even though I
    didn't assign \$i to a variable. This too is unsurprising. This
    probably works with a reference to any variable.

    - "undef" is identical, and without a warning.

    I'm sure I'm overlooking some other scalar value types. And I cannot
    try every value even of the types I know about -- qr/acc/ is simple
    enough that Perl knows it's identical to another instance, but for all
    I know, if there's a certain more complicated expression or some
    certain modifier, Perl doesn't understand equality (much like sub{}).

    So is there documentation for what keys are considered equal?

    I don't think there's an operator to check for that equality
    (other than "sub hashequal { my ($a, $b) = @_; my %t = ($a, 1); return exists $t{$b}; }")

    --
    Tim McDaniel,
     
    Tim McDaniel, Mar 1, 2012
    #1
    1. Advertising

  2. (Tim McDaniel) writes:
    > I tried "man perldata", but I didn't notice anything applicable.
    >
    > I've always used only strings as hash keys -- I've just assumed
    > without any evidence that they're the only things that work.
    > But it occurred to me to wonder what else could be used as keys.


    [...]

    > $hash = {
    > 'SCALAR(0x116ede20)' => 'narf',
    > 'undef' => 'WTF?',
    > 'CODE(0x116f4200)' => 'poit',
    > 'CODE(0x116ede80)' => 'hurple',
    > '(?-xism:acc)' => 'zing'
    > };


    [...]

    > So I'm thinking that, in Perl, hash keys can also be any scalar.
    > Is that documented anywhere?


    It is documented:

    Hashes are unordered collections of scalar values indexed by
    their associated string key.
    [perldata(1)]

    This means that if you use something which is not a string as hash
    key, that something is stringified and the resulting string becomes
    the actual key.
     
    Rainer Weikusat, Mar 1, 2012
    #2
    1. Advertising

  3. Tim McDaniel

    Tim McDaniel Guest

    In article <>,
    Rainer Weikusat <> wrote:
    > (Tim McDaniel) writes:
    >> I tried "man perldata", but I didn't notice anything applicable.
    >>
    >> I've always used only strings as hash keys -- I've just assumed
    >> without any evidence that they're the only things that work.
    >> But it occurred to me to wonder what else could be used as keys.

    >
    >[...]
    >
    >> $hash = {
    >> 'SCALAR(0x116ede20)' => 'narf',
    >> 'undef' => 'WTF?',
    >> 'CODE(0x116f4200)' => 'poit',
    >> 'CODE(0x116ede80)' => 'hurple',
    >> '(?-xism:acc)' => 'zing'
    >> };

    >
    >[...]
    >
    >> So I'm thinking that, in Perl, hash keys can also be any scalar.
    >> Is that documented anywhere?

    >
    >It is documented:
    >
    > Hashes are unordered collections of scalar values indexed by
    > their associated string key.
    > [perldata(1)]
    >
    >This means that if you use something which is not a string as hash
    >key, that something is stringified and the resulting string becomes
    >the actual key.


    *light dawns over Marblehead* Why, lookie at all those *QUOTATION MARKS*
    in the key positions in the Data::Dumper->Dump output, as opposed to
    what it outputs when given a real reference!

    Thank you. I blush.

    I just realized that
    $hash{undef} = 'WTF?';
    was wrong: "undef" is interpreted as a string, of course.
    $hash{undef()} = 'WTF?';
    gives a warning "Use of uninitialized value in hash element" and
    the key is a null string.

    --
    Tim McDaniel,
     
    Tim McDaniel, Mar 1, 2012
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Edward Rutherford

    Comparing fp types for equality

    Edward Rutherford, Dec 20, 2011, in forum: C Programming
    Replies:
    12
    Views:
    442
    Rui Maciel
    Dec 20, 2011
  2. Une bévue
    Replies:
    5
    Views:
    176
    Une bévue
    Aug 10, 2006
  3. James
    Replies:
    2
    Views:
    144
    James
    Mar 18, 2009
  4. Matt Hicks
    Replies:
    7
    Views:
    254
    Peter J. Holzer
    Dec 23, 2012
  5. Rainer Weikusat
    Replies:
    5
    Views:
    234
    Rainer Weikusat
    Dec 19, 2012
Loading...

Share This Page