Note that I have no idea on the answer to this, as it's not intuitively following from what is out there in perldata.

In reference to a recent question on multi-keyed hashes, I got to wondering exactly what the perl hash could take. We know that :

my %hash; @hash{ 3,4 } = qw( perl hacker ); print join ",", keys %hash; # prints "3,4"
Since that is your hash slice. But I got to wondering, what if you accidently called this in scalar form, that is:
my %hash; $hash{ 3,4 } = qw( perl hacker ); print join ",", keys %hash; # ????
I initially thought that the comma operator, forcing output as a list, would be done first, and thus the hash step would convert the list to a scalar (or in this case, '2') and use that as the key, but I was wrong. When I ran this, I got "34", that is, there was a single key in the hash. But this was on linux; on windows (both 5.005 and 5.6.1), I got "34" (if that doesn't come out correctly, the middle symbol looks like a reduced capital L.) A bit more digging shows up that linux actually has an invisible symbol there, represented by less as '^\'. Weirrrd.

Thinking that the hash might be interpreting this strangely, I tried the following:

my %hash; $hash{ (3,4) } = qw( perl hacker ); print join ",", keys %hash; # ????
Again, the same result occured.

Obviously, going to :

my %hash; $hash{ [3,4] } = qw( perl hacker ); print join ",", keys %hash; # ????
gives "ARRAY(0xDEADBEEF)" or some such like that, which isn't a surprise at all.

Was this reliable?

my %hash; $hash{ 3,4 } = qw( perl hacker ); print $hash{ 3,4 }, "\n";
Which results in "hacker". Very interesting...

Variables work with no problem:

my %hash; for my $i (0..5) { for my $j (0..5) { $hash{ $i,$j } = $i*$j; } } foreach ( keys %hash ) { print "$_ : ", $hash{ $_ }, "\n"; }
This code prints out the correct multiplication with each 'key'. This also works with any number of 'keys', eg expanding the above to $i, $j, $k.

So I have tumbled accidently into a way to do multidimensional hashes? I know this isn't the most elegant solution, but something seems to be working. Would it be possible to split on this odd key, such that one can make grep { nth_element_of_the_key eq 'test' } keys %hash;


Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain

Replies are listed 'Best First'.
Re: An interesting oddity with hashes
by wog (Curate) on Jun 02, 2001 at 07:09 UTC
    This is actually well-documented in perlvar. See $; AKA $SUBSEP AKA $SUBSCRIPT_SEPERATOR.
Re: An interesting oddity with hashes
by chipmunk (Parson) on Jun 03, 2001 at 00:58 UTC
    So I have tumbled accidently into a way to do multidimensional hashes?
    Yes. You've actually stumbled upon the perl4 implementation of multi-dimensional hashes. This feature was designed before hard references existed in the language. With perl5, real multidimensional hashes are of course preferred.
(tye)Re: An interesting oddity with hashes
by tye (Sage) on Jun 02, 2001 at 10:39 UTC

    Quick, what does this print?

    my %hash; my @arr= qw( This is a test ); $hash{@arr}= 1; $hash{@arr[0,1,2,3]}= 2; $hash{@arr[0,1],@arr[2,3]}= 3; print join $/, sort(keys %hash), "";

            - tye (but my friends call me "Tye")
Re: An interesting oddity with hashes
by Vynce (Friar) on Jun 02, 2001 at 12:14 UTC

    perhaps i'm dense, but i don't see how this gives you any more multidimensional functionality than hashes of hashes, e.g.:

    $hash{6}{times}{9} = 42; $hash{2}{plus}{2} = 5;

    the one thing i often find i want to do with the hash-of-hash notation that i can't, easily, is make slices that keep their shape via place-holders, like:

    $hash{0}{plus}{0} = 0; $hash{0}{plus}{1} = 1; $hash{1}{plus}{0} = 1; $hash{1}{plus}{1} = 10; %plus = %hash{}{plus}{}; # (or something like it) # should yield: # $plus{0}{0} = 0; # $plus{0}{1} = 1; # $plus{1}{0} = 1; # $plus{1}{1} = 10;

    or something like that. hash-wise hash slices. but i don't see your trick helping, there.