http://www.perlmonks.org?node_id=576309


in reply to Re: HASH keys preserve class ?
in thread HASH keys preserve class ?

ikegami,
To be pedantic about it, hash key values can only be scalars. A reference happens to be a scalar so a hash value can get to anything you can reference. Since you can reference just about anything under the sun, you can can get to just about anything.

To be less pedantic, I thought I heard someone say there was an XS way to make hash keys non-string but I know nothing about it beyond a vague recollection.

Cheers - L~R

Replies are listed 'Best First'.
Re^3: HASH keys preserve class ?
by ikegami (Patriarch) on Oct 04, 2006 at 15:26 UTC

    First you say keys are scalars not strings, then you say there might be a way of allowing things other than strings.

    Except possibly through an XS trick, keys can only be strings. perldata confirms this: "Hashes are unordered collections of scalar values indexed by their associated string key." If you try to use a reference as a key, the reference will not be a key of the hash. It's string representation will.

    I guess your point was that you could attempt to use a non-string as a key. That is indeed valid. The scalar will be stringified before being used as a key.

    The following is an attempt to use a reference as a key in a hash:

    use strict; use warnings; my @var = qw( a b c ); my $ref = \@var; my %hash; $hash{$ref} = 1; foreach (keys %hash) { print @$_, "\n"; }

    In the latest Perl (5.8.8), the above code outputs

    Can't use string ("ARRAY(0x225fb8)") as an ARRAY ref while "strict ref +s" in use
      ikegami,
      First you say keys are scalars not strings

      Hrmm. I guess I should have proofed my response a 4th time before submitting. The first paragraph was intended to address "values" and the second "keys". Where I said "...hash key values can only be scalars.", I meant hash values. In fact, I said that later on in the same paragraph "...so a hash value can...".

      Regarding non-string keys - I assume some trickery that can only be done in XS land would get around perldata. Of course, I don't remember who I heard discussing it or if I understood what they were saying but I suspect it would have been diotalevi or perhaps demerphq.

      In any case, my correction to your post was concerning values only. Sorry my incorrect wording implied otherwise.

      Cheers - L~R

        It's certainly possible to reverse the stringyfication of references.

        #! perl -slw use strict; use Data::Dumper; use Devel::Pointer; my @a = 1.. 10; my %b = 'a'..'z'; my $c = \ 'A readonly scalar'; my $d = 'a scalar'; my %hash; $hash{ $_ } = 1 for \( @a, %b, $c, $d ); for ( keys %hash ) { m[([^(]+)\(([^)]+)\)] and $1 eq 'HASH' ? print( Dumper unsmash_hv( oct( $2 ) ) ) : $1 eq 'ARRAY' ? print( Dumper unsmash_av( oct( $2 ) ) ) : $1 eq 'REF' ? print( ${ unsmash_sv( oct( $2 )) } ) : $1 eq 'SCALAR'? print( unsmash_sv( oct( $2 ) ) ) : print "Unknown type '$1'"; } __END__ C:\test>junk9 A readonly scalar $VAR1 = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]; a scalar $VAR1 = { 'w' => 'x', 'e' => 'f', 'a' => 'b', 'm' => 'n', 's' => 't', 'y' => 'z', 'u' => 'v', 'c' => 'd', 'k' => 'l', 'q' => 'r', 'g' => 'h', 'i' => 'j', 'o' => 'p' };

        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.