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

Hi reader !
I got such problem - I want retrieve keys of hash, but seems like I got something wrong:
@hash{'one'} = "123"; @hash{'two'} = "123"; @hash{'three'} = "123"; foreach ($key = keys(%hash)) { print "key is - $key\n"; }
I'm excpecting:
one two three
but, I got number of keys.

Why ? Where I'm wrong ?

Thanks for any answers.

20040729 Edit by ysth: use code, p, and br tags instead of pre

Replies are listed 'Best First'.
Re: hash and it's keys...
by Limbic~Region (Chancellor) on Jul 29, 2004 at 19:52 UTC
    stan2004,
    Well, you have both done it wrong and done it right. The correct syntax of a for loop of this type is:
    # pseudo for <variable> ( list ) { # some code presumably using variable } # real for my $key ( keys %hash ) { print "$key\n"; }
    You may omit the <variable> and perl will happily stick the current alias from the list into $_ (see perldoc perlvar).

    You have chosen not use warnings and strictures so you didn't get told about the other things you did wrong. This is a testimony to how far Perl will go to do what you mean. The correct way to assign a value to a hash key is:

    #psuedo $hash{<key>} = <value>; #read $hash{foo} = 'bar';
    You can however assign multiple values to multiple keys at once using a hash slice. The syntax is
    #pseudo @hash{<list of keys>} = <list of values>; #real @hash{ @keys } = @values;
    Finally, keys returns a list of keys in a hash in list context, but the number of keys in scalar context. That is why you got the list of keys. It sounds like you still have a lot to learn. See the various perldocs, check out the tutorials section, check out http://learn.perl.org.

    Cheers - L~R

Re: hash and it's keys...
by gaal (Parson) on Jul 29, 2004 at 19:49 UTC
    In versions of Perl up to and including 5, the proper way to refer to a hash element is $hash{elem}. Using a @ works but is less efficient; if you run perl with warnings (-w) you'll get a notice to that effect.

    The foreach line should be spelled like this:

    foreach my $key (keys %hash) {
    Hope this helps.
Re: hash and it's keys...
by ysth (Canon) on Jul 29, 2004 at 19:52 UTC
    First of all, put "use warnings;" at the top of your code; it will help you immensely with all kinds of problems.

    @hash{'one'} = "123" does work, but is better said as $hash{'one'} = "123".

    $key = keys... is calling keys in a scalar context (asking for only one value). keys is documented to return the number of keys in the hash in this case. Say foreach my $key (keys %hash) instead, or while (my $key = each %hash).

Re: hash and it's keys...
by Fletch (Bishop) on Jul 29, 2004 at 19:51 UTC

    You either mean to use for my $key ( keys %hash ) { ... } or while( my $key = each %hash ) { ... }. You get the number of keys in the hash when you use it in a scalar context. See perldoc -f keys. And also @hash{'one'} is wrong; that's a one key hash slice, when what you really mean is $hash{'one'}.

Re: hash and it's keys...
by Anonymous Monk on Jul 30, 2004 at 04:59 UTC

    The problem in your code is,

    you are assigning the number of keys in the hash to the variable $key.

    Use,

    foreach $key (keys %hash){ print $key."\n" }