http://qs1969.pair.com?node_id=334812

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

Hi,

I have the following requirement and the following code doesnt get me anywhere...Please help Sample Code is pasted below followed by the requirement....

%ABCDev=qw/A 1 B 2 C 3/; %DEFDev=qw/D 4 E 5 F 6/; %GHIDev=qw/G 7 H 8 I 9/; @prods=qw/ABC DEF GHI/; for($i=0;$i<=$#prods;$i++) { $prodDev=$prods[[$i]]."Dev"; @prodkeys = keys%{$prodDev}; print "@prodKeys"; } #Expected Result of the above is # First loop it must return 1 2 3 # Second loop it must return 4 5 6 # Third Loop it must return 7 8 9

update (broquaint): tidied up formatting + added <code> tags

Replies are listed 'Best First'.
Re: Runtime Hash Variable access
by Juerd (Abbot) on Mar 08, 2004 at 14:08 UTC

    $ABCDev=qw/A 1 B 2 C 3/;

    Print $ABCDev to see what happened. It was assigned only the 3. The qw operator evaluates to its last element when used in scalar context. You need to learn what a hash is before you can use one. Hashes are a very basic part of Perl and any tutorial or learning book covers them. I think you should read Beginning Perl or something like that. Or at least perlintro.

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

Re: Runtime Hash Variable access
by Hena (Friar) on Mar 08, 2004 at 14:14 UTC
    First, use code tags here, ok.

    I assume you don't use 'use warnings' here? You neeed to use it catch problems like these. Eg you haven't declared any hashes. Should be like this:
    %ABCDev = qw /A 1 B 2 C 3/;
    But, i'm not sure if the loop will work either. You need to try it again. It might be better to save references into array.
    @prods=(\%ABCDev,\%DEFDev,\%GHIDev); for($i=0;$i<=$#prods;$i++) { @prodkeys = keys %{$prods[$i]}; print "@prodKeys\n"; }

      %ABCDev = qw /A 1 B 2 C 3/;

      Technically, that *defines* (assigns to) %ABCDev, but it doesn't *declare* it. You declare a variable with my, our or use vars.

      Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

        You are right. Mainly ment that the wanted hash %ABCDev was empty due that assingment happened to scalar and not hash. And that using 'use strict' and 'use warnings' would have caught the mistake.

        I just don't always think that much about words than meaning (which in some cases can be somewhat obscure due to my lack of attention to words :D).
      Your code worked fine. Except I had to change the prodKeys to prodkeys :-) Thanks for immediate reply
Re: Runtime Hash Variable access
by muba (Priest) on Mar 08, 2004 at 14:21 UTC
    Well... not only applies the reply above. Also your way of accessing a variable by it's name from a string is not correct. According to your code, you think you can do this with:
    $prods[[$i]]."Dev"

    I would say this is the way:
    ${"${prods[[$i]]}Dev"}

    Although I don't know if that would work here, because of the [[$i]]. It's a pity I don't have a Perl installation here (@school).

    update: note: the first example would give you the value of $prods[[$i]] and "Dev". So to say, if $prods[[$i]] eq "Web" (just another Perl example!), then your code would result in "WebDev", which actually is nice thing to do, but it's not what you want. /update

      Note also that symbolic references like this are very bad style and disallowed by strict 'refs' for a very good reason. If you read a good book (like Beginning Perl), you learn that a hash of hash references is much better than accessing global hashes by variable symbol names.

      I don't think the OP knows Perl and think any help is a waste if they don't read a good book or tutorial. This site has many resources that can help them, most of which can be found on the Tutorials page.

      Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

        What I was doing in my reply is called a sumbolic reference?

        $the_var_i_want = "this is the actual value I want to get"; $the_name = <STDIN>; #say, this would be "the_var\n" chomp $the_name; print ${"${the_name}_i_want"};
        And that is deprecated? Why is that? I think it's quite a nice way of getting the value of a variable which name you don't yet know.