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

Is there a way to make a hash key a reference to another key in the same hash? It is also a multi dimentional hash and has to be able to get pass through Data::Dumper to be dumped into a file and eval'ed back later. Here what I'm thinking of
%hash = ( 'key' => { 'stuff' => 'more stuff', 'other stuff' => 'even more stuff', }, 'ref to key' => \%hash{'key'}, );

Replies are listed 'Best First'.
Re: Hash keys reference
by japhy (Canon) on Mar 04, 2002 at 03:14 UTC
    You can't refer to $hash{key} until it exists, and it doesn't exist until that hash creation is done. You'll need to do it separately.

    However, you can do something bizarre like this:

    my @foo; @foo[0..2] = (10, \$foo[0], 20); print ${ $foo[1] }; # 10
    That works, while
    my @foo; @foo = (10, \$foo[0], 20); print ${ $foo[1] }; # nothing
    does not. ;)

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a (from-home) job
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

      Well, actually, the reference makes it exist. It's the hash assignment that delinks it. Witness the result of:
      %last_name = (); $x = \$last_name{fred}; # creates hash element, value is undef $last_name{fred} = "flintstone"; print $$x; # prints flintstone
      So, your array-slice example would also work on a hash slice:
      undef %last_name; @last_name{qw(fredref fred)} = (\$last_name{fred}, " +flintstone");

      -- Randal L. Schwartz, Perl hacker

        Yes, I'm fully aware of that, which is why I used the example. ;)

        _____________________________________________________
        Jeff[japhy]Pinyan: Perl, regex, and perl hacker, who'd like a (from-home) job
        s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: Hash keys reference
by Juerd (Abbot) on Mar 04, 2002 at 08:30 UTC
    The question has already been answered, but I'd like to point out that even if it were possible, \%hash{'key'} wouldn't be working. You want a single element, a scalar, so it'd be \$hash{'key'} instead.

    Let's cheat!

    If you want the references in the hash assignment for readability, and don't use anonymous subs in it, you could abuse those:
    %hash = ( foo => 'bar', bar => sub { 'foo' } ); (ref() eq 'CODE') && $_ = \$hash{ $_->() } for values %hash;

    Same goes for any type of reference. So if you don't use anonymous arrays, you could use:
    %hash = ( foo => 'bar', bar => [ 'foo' ] ); (ref() eq 'ARRAY') && $_ = \$hash{ $_->[0] } for values %hash;

    You could of course cheat using some common prefix of which you're sure not to use it for any other purpose:
    %hash = ( foo => 'bar', bar => 'REF:foo' ); /^REF:(.+)/ and $_ = \$hash{$1} for values %hash;

    Or just replace the hash assignment with a lot of key assignments:
    %hash = (); for ( [ foo => 'bar' ], [ bar => \$hash{foo} ] ) { $hash{ $_->[0] } = $_->[1]; }

    Or use a temporary hash:
    %hash = (); %temp = ( foo => 'bar', bar => \$hash{foo} ); $hash{$_} = $temp{$_} for keys %temp;


    BTW: I'm not really being serious.

    ++ vs lbh qrpbqrq guvf hfvat n ge va Crey :)
    Nabgure bar vs lbh qvq fb jvgubhg ernqvat n znahny svefg.
    -- vs lbh hfrq OFQ pnrfne ;)
        - Whreq
    

Re: Hash keys reference
by jsegal (Friar) on Mar 04, 2002 at 15:48 UTC
    If I am reading your question correctly, there is also a simpler way to get what you want, as long as you don't need to define the structure in a single statement. Predefine your multiple references.
    eg:
    my $keyval1 = { 'stuff' => 'more stuff', 'other stuff' => 'even more stuff', }; %hash = ( 'key' => $keyval1, 'ref to key' => $keyval1, );
    Data::Dumper will work with this structure if you set Purity to 1 (see Data::Dumper for the different ways to do this.
    Good luck,

    --JAS
Re: Hash keys reference
by dash2 (Hermit) on Mar 04, 2002 at 13:30 UTC
    There is a module Array::RefElem which does this sort of thing for arrays; search.cpan.org seems to be down, but if it is up you could look for Hash::RefElem, maybe.

    dave hj~

    PS... hmm, no hash version. What exactly do you want to do this for, btw?

Re: Hash keys reference
by rendler (Pilgrim) on Mar 05, 2002 at 04:45 UTC
    All these solutions seem to be over complicated to me so I decided to reserve a key in the hash (aliases). Basically that key contains other keys whose values are the name of the main keys. It adds extra overhead to the script but the simpleness of it seems to outweight any extra overheads.