You have a few things confused here. If the sigil (the sign in front of the var name) is a $, you have a scalar value.
Here is a list of things you need to remember:
- Both
$hash and $arr_ref are references, so the variable names have a $ because they only store a memory address reference to where the actual hash/array is.
- An array has a
@ sigil, and a hash has a % sigil. So @array and %hash are both not references.
- If you want to put a data structure into another data structure in Perl, you need to reference it. This is done by putting a
\ in front of the variable name like $ref = \@array.
- An array gets a list assigned:
my @colors = ( 'red', 'green' );
- A hash gets a list (with parenthesis) assigned:
%count = ( 'red' => 5, 'green' => 2 );
- To access a hash value, use
$count{'red'}. The sigil changes to $ because the value behind the whole identifier count{'red'} is now a scalar value.
- To access an array value, use
$colors[0] (which will give 'red'.
- The
keys function returns a list.
- Forcing a list or an array into scalar context will give its number of elements.
Now with all this knowledge you will see that when you assign keys($hash) to $arr_ref, you are forcing scalar context, thus you get the count.
- If you want an array of the keys, use
my @array = keys($hash).
- If you want an array ref, use
my $arr_ref = \keys($hash) or put the list that is returned by keys into an array ref like my $arr_ref = [ keys($hash) ].
Also note that Perl's keys built-in only recently learned to handle references. You should be giving it a hash, or dereference your hash ref like keys( %{ $hash_ref } ). This can be shortened to keys %$hash_ref.
Also, always use strict and use warnings as both will help you by telling you about things you did wrong or things that you might have gotten confused.
To illustrate some more, I have rewritten your first piece of code to three different forms.
No references:
use strict;
use warnings;
use Data::Dumper;
my %hash = (
1 => "asd",
21 => "fafafa"
);
my @array_of_keys = ();
for my $key ( keys %hash )
{
push @array_of_keys, $key;
}
print Dumper( \@array_of_keys ); # reference the array because it looks nicer in Dumper
Reference for the array:
use strict;
use warnings;
use Data::Dumper;
my %hash = (
1 => "asd",
21 => "fafafa"
);
my $arrayref_of_keys = [];
for my $key ( keys %hash )
{
push @$arrayref_of_keys, $key; # or @{ $foo }
}
print Dumper( $arrayref_of_keys ); # it's already a ref, so no need for \
All references:
use strict;
use warnings;
use Data::Dumper;
my %hashref = { # notice the curly braces instead of round parens
1 => "asd",
21 => "fafafa"
};
my $arrayref_of_keys = [];
for my $key ( keys %$hashref ) # or %{ $foo }
{
push @$arrayref_of_keys, $key; # or @{ $foo }
}
print Dumper( $arrayref_of_keys );
I suggest you read perlref and perlreftut.
my $hash = {};has absolutely no purpose in both your examples. Remove that line and it will make no difference. A Perl variable is the type of whatever was last assigned to it. So although the linemy $arr_ref = [];makes$arr_refa reference to an array at that point, the line$arr_ref = keys($hash)provides a scalar context tokeys(), resulting in the length of the array being returned. It needs to be@$arr_ref = keys($hash)to provide an array context.