Reputation: 3172
There is a twist obviously. When I do it like that it works and contains all the keys:
my $hash = {};
$$hash{1} = "asd";
$$hash{21} = "fafafa";
for my $key (keys($hash))
{
push($arr_ref, $key);
}
print Dumper($arr_ref);
However when I try to do it the following way I only get the number of the keys:
my $hash = {};
$$hash{1} = "asd";
$$hash{21} = "fafafa";
my $arr_ref = [];
$arr_ref = keys($hash);
In my head both things should be the same and after all if I do it like that:
my @arr = keys($hash);
@arr
will contain the keys of the hash.
The question is where is the difference ?
Upvotes: 1
Views: 313
Reputation: 50657
use strict;
would be helpful along with use warnings;
, try
@$arr_ref = keys($hash);
as $arr_ref = keys($hash);
is implicit version of $arr_ref = scalar keys($hash);
and ensures scalar context
in both cases.
Also notice that keys $scalar
is experimental, and keys %$scalar
is advised.
Upvotes: 3
Reputation: 54373
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:
$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.@
sigil, and a hash has a %
sigil. So @array
and %hash
are both not references.\
in front of the variable name like $ref = \@array
.my @colors = ( 'red', 'green' );
%count = ( 'red' => 5, 'green' => 2 );
$count{'red'}
. The sigil changes to $
because the value behind the whole identifier count{'red'}
is now a scalar value.$colors[0]
(which will give 'red'
.keys
function returns a list.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.
my @array = keys($hash)
. 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.
Upvotes: 4