Reputation: 13
I am trying to write a subroutine that takes in a hash of arrays as an argument. However, when I try to retrieve one of the arrays, I seem to get the size of the array instead of the array itself.
my(%hash) = ( );
$hash{"aaa"} = ["blue", 1];
_subfoo("test", %hash);
sub _subfoo {
my($test ,%aa) = @_;
foreach my $name (keys %aa) {
my @array = @{$aa{$name}};
print $name. " is ". @array ."\n";
}
}
This returns 2 instead of (blue, 1) as I expected. Is there some other way to handle arrays in hashes when in a subroutine?
Apologies if this is too simple for stack overflow, first time poster, and new to programming.
Upvotes: 1
Views: 120
Reputation: 434665
You're putting your @array
array into a scalar context right here:
print $name. " is ". @array ."\n";
An array in scalar context gives you the number of elements in the array and @array
happens to have 2 elements. Try one of these instead:
print $name . " is " . join(', ', @array) . "\n";
print $name, " is ", @array, "\n";
print "$name is @array\n";
and you'll see the elements of your @array
. Using join
lets you paste the elements together as you please; the second one evaluates @array
in list context and will mash the values together without separating them; the third interpolates @array
by joining its elements together with $"
(which is a single space by default).
Upvotes: 10
Reputation: 67900
As mu is too short has mentioned, you used the array in scalar context, and therefore it returned its length instead of its elements. I had some other pointers about your code.
Passing arguments by reference is sometimes a good idea when some of those arguments are arrays or hashes. The reason for this is that arrays and hashes are expanded into lists before being passed to the subroutine, which makes something like this impossible:
foo(@bar, @baz);
sub foo { # This will not work
my (@array1, @array2) = @_; # All the arguments will end up in @array1
...
}
This will work, however:
foo(\@bar, \@baz);
sub foo {
my ($aref1, $aref2) = @_;
...
}
You may find that in your case, each
is a nice function for your purposes, as it will make dereferencing the array a bit neater.
foo("test", \%hash); # note the backslash to pass by reference
sub foo {
my ($test, $aa) = @_; # note use of scalar $aa to store the reference
while (my ($key, $value) = each %$aa)) { # note dereferencing of $aa
print "$key is @$value\n"; # ...and $value
}
}
Upvotes: 4