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

what is the correct way to use other kinds of variables (which are instantiated as strings) as the keys to a hash, for instance:
%simpsons = ("father" => "homer", "mother" => "marge", "son" => "bart" +, "daughter" => "lisa"); #deprecated maggie $string = "simpsons"; @array = ("simpsons"); %hash = ("family" => "simpsons"); print("$simpsons{father}\n"); #case1 prints "homer" print("$$string{mother}\n"); #case2 prints "marge" print("$$array[0]{son}\n"); #case3 err print("$$hash{family}{daughter}\n"); #case4 err
Cases 1& 2 work, case 3 can be made to work with:
$ar = $array[0]; print("$$ar{son}\n");
But there must be a better way.
I would appreciate a helpful monk pointing me in the correct direction.
Thanks,
Ntav.

Replies are listed 'Best First'.
Re: using other variables as keys to hash
by davorg (Chancellor) on Sep 12, 2001 at 15:10 UTC

    You're trying to use symbolic references (aka "using a variable as a variable name"). This is a very bad idea. Reasons why it is a bad idea are discussed at length by Dominus here, here and here. In fact it's such a bad idea, that had you put use strict in your program (as you always should) you would have got errors with case 2 as well. This is a good thing!

    The solution to your problem is to read up about references and complex data structures in Perl. The perlreftut and perldsc manual pages would be a good start.

    --
    <http://www.dave.org.uk>

    Perl Training in the UK <http://www.iterative-software.com>

Re: using other variables as keys to hash
by MZSanford (Curate) on Sep 12, 2001 at 15:08 UTC
    This is actually a bit of refrence-tastic syntactic sugar. Here is a working version :
    print("$simpsons{father}\n"); print("$$string{mother}\n"); print("${$array[0]}{son}\n"); print("${$hash{family}}{daughter}\n");
    The additional currlies clarify which potion is the hash reference, and which part is the key.
    speling champ of tha claz uf 1997
    -- MZSanford

      There aren't any hash references in this example, just symbolic references. Running your code under use strict gives the following error:

      Can't use string ("simpsons") as a HASH ref while "strict refs" in use at ./test.pl line 11. --
      <http://www.dave.org.uk>

      Perl Training in the UK <http://www.iterative-software.com>

        ok, but i think "HASH ref" means the symbolic reference was referencing a hash. you were probably correct in you're first post, that symbolic references are usually not a good idea.
        enemy of the XP whores of the world
        -- MZSanford
Re: using other variables as keys to hash
by VSarkiss (Monsignor) on Sep 12, 2001 at 19:02 UTC

    Both davorg and MZSanford have pointed out above that you're using symbolic references and hinted why that's a bad idea ;-) Just to complete the picture, here's what your code would look like using true or "hard" references.

    use strict 'refs'; # Catches use of symbolic references, # though plain "use strict" would be even better # Quotes are not necessary on the LHS of => %simpsons = ( father => "homer", mother => "marge", son => "bart", daughter => "lisa", ); # Here's the code that uses symbolic refs: #$string = "simpsons"; #@array = ("simpsons"); #%hash = ("family" => "simpsons"); #print("$simpsons{father}\n"); #case1 prints "homer" #print("$$string{mother}\n"); #case2 prints "marge" #print("$$array[0]{son}\n"); #case3 err #print("$$hash{family}{daughter}\n"); #case4 # Here are the hard refs. $string = \%simpsons; @array = (\%simpsons); %hash = (family => \%simpsons); # Not necessary to quote variables to print print $simpsons{father}, "\n"; #case1 prints "homer" print $$string{mother}, "\n"; #case2 prints "marge" print $string->{mother}, "\n"; #also prints "marge" print ${$array[0]}{son}, "\n"; #case3 prints "bart" print $array[0]->{son}, "\n"; #also prints "bart" print ${$hash{family}}{daughter}, "\n"; #"lisa" print $hash{family}->{daughter}, "\n"; #also "lisa" print $hash{family}{daughter}, "\n"; #also "lisa"
    For more information on the backslash operator for taking references and the syntax for getting at its contents, take a look at the doco on references.

    HTH

Re: using other variables as keys to hash
by runrig (Abbot) on Sep 12, 2001 at 19:46 UTC
    Another solution to avoid symbolic references would be to make the string "simpsons" one of the hash keys:
    %family = ( simpsons=>{ father => "homer", mother => "marge", son => "bart", daughter => "lisa", }); #deprecated maggie $string = "simpsons"; @array = ("simpsons"); %hash = ("family" => "simpsons"); print("$family{$array[0]}{son}\n"); print("$family{$hash{family}}{daughter}\n");