I've been toying with hashes in Perl. The following works as expected:
use strict;
use warnings;
sub cat {
my $statsRef = shift;
my %stats = %$statsRef;
print $stats{"dd"};
$stats{"dd"} = "DDD\n";
print $stats{"dd"};
return ("dd",%stats);
}
my %test;
$test{"dd"} = "OMG OMG\n";
my ($testStr,%output) = cat (\%test);
print $test{"dd"};
print "RETURN IS ".$output{"dd"} . " ORIG IS ". $test{"dd"};
Output is:
OMG OMG
DDD
OMG OMG
RETURN IS DDD
ORIG IS OMG OMG
When I add an array into the mix however it errors out.
use strict;
use warnings; sub cat {
my $statsRef = shift;
my %stats = %$statsRef;
print $stats{"dd"};
$stats{"dd"} = "DDD\n";
print $stats{"dd"}; return ("dd",("AAA","AAA"),%stats); }
my %test; $test{"dd"} = "OMG OMG\n";
my ($testStr,@testArr,%output) = cat (\%test);
print $test{"dd"};
print "RETURN IS ".$output{"dd"} . " ORIG IS ". $test{"dd"}. " TESTARR IS ". $testArr[0];
The output is:
OMG OMG
DDD
OMG OMG
Use of uninitialized value in concatenation (.) or string at omg.pl line 20.
RETURN IS ORIG IS OMG OMG
TESTARR IS AAA
Why is the array displaying but the hash is not?
All lists got automatically flattened in Perl. Therefore the assignment operator won't be able to magically distinguish the border between the lists returned by your subroutine. In your case it means that @testArr will consume the resulting list given by cat
, and %output will get none of it - hence the Use of unitialized value...
warning.
If you need to return a hash or array specifically, use references:
return ("dd", ["AAA", "AAA"], \%stats);
... and later, in the assignment:
my ($testStr, $testArrayRef, $testHashRef) = cat(...);
my @testArray = @$testArrayRef;
my %testHash = %$testHashRef;