spx2 has asked for the wisdom of the Perl Monks concerning the following question:

in this node it was asked by a monk if it is possible
to make hashes that map array to strings.
I have seen very often that when debugging code I sometimes make mistakes and treat arrayrefs
as arrays and for example instead of printing an array I print the array ref and the following
kind of strings appear.
For example this code perl -e '@a=("a","b","c");print \@a;' outputs here ARRAY(0x814f60c)

Ofcourse,I suppose the number there is probably dependent on the memory manager that perl uses,
and on the machine its running.
*What I want to ask is if this string could be used as a key for the hash,actually if it is unique for
every array wich is used inside a perl program
Moreover,if the previous supposition(*) would be true,can a perl coder use that string to return
to the array that is associated with that string ?

thank you

Replies are listed 'Best First'.
Re: pointers == arrayrefs ?
by JStrom (Pilgrim) on Jan 09, 2008 at 01:09 UTC
    Tie::RefHash may be what you're looking for (it preserves the reference-ness of the keys) and I believe it's part of the standard distribution.
Re: pointers == arrayrefs ?
by rafl (Friar) on Jan 09, 2008 at 00:25 UTC

    If you're really sure that's what you want you might want to take a look at Tie::Hash::StructKeyed and its implementation.

Re: pointers == arrayrefs ?
by graff (Chancellor) on Jan 09, 2008 at 06:06 UTC
    What I want to ask is if this string could be used as a key for the hash,actually if it is unique for every array wich is used inside a perl program

    I'm not sure what sort of usage you have in mind, but if you want to count on the "pointer" (memory-address) values of references always being different, this will depend on whether your app happens to create multiple references to the same thing. In it's simplest form, it would involve something like this:

    my @a = (5..10); my $aref = \@a; #... my $anotheref = $aref; #... my %h = ( $aref => 'first one', $anotheref => 'second one' );
    If you test that out, you'll see that only one hash element is created, and the hash value is "second one", because the (stringified) memory-address values of $aref and $anotheref are identical. Of course, there are more convoluted, complicated, circuitous ways to arrive at the same effect (to enhance your debugging experience).

    But if you are confident that you are handling only one reference to each distinct array in a script, then there should be no problem with each memory address being a hash key. The only limitation is that you are not able, thereafter, to use the hash keys as references -- that is, you cannot dereference a hash key, because hash keys can be nothing other than strings.

    That's why the initial replies pointed you to those CPAN modules, in case you actually want things to "work both ways" in some sense (where references are used as hash keys, and hash keys can still be used as references). But I'd have to wonder about how useful a memory address would be as a hash key... usually, the hash key is something that carries semantic importance relevant to the associated value (if any), or to some aspect of the application. Memory addresses don't have that property.

Re: pointers == arrayrefs ?
by snoopy (Curate) on Jan 09, 2008 at 06:56 UTC
    Some experimentation:
    #!/usr/bin/perl use warnings; use strict; my %seen; for (0...1000) { my $a = [0..sprintf("%d", 1 + rand(20))]; die "$_ iteratations: I've already seen $a" if exists $seen{$a}; $seen{$a} = 1; }
    This dies unpredictably (varying number of iterations and at different addresses), eg:
    8 iteratations: I've already seen ARRAY(0x180bc0c) at at1.pl line 9.
    However, if I change the last line to
    $seen{$a} = $a; # capture the reference
    ..then my program does run to completion.

    Addresses are unique when arrays are current. But they may become invalid and/be reused when arrays go out of scope.