T
Tim McDaniel
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:umper;
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:umper->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}; }")
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:umper;
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:umper->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}; }")