Reputation: 1813
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?
Upvotes: 1
Views: 416
Reputation: 5222
in addition to the answer by raina77ow I would highly recommend just passing references about, rather than translating from type to reference and back again. It's a lot easier to read and less hassle to code (imho)
use Data::Dumper;
use strict;
use warnings;
sub cat {
my $statsRef = shift;
print $statsRef->{"dd"} ;
$statsRef->{"dd"} = "DDD\n";
print $statsRef->{"dd"} ;
return ("dd",["AAA","AAA"],$statsRef);
}
my $test = {} ;
$test->{"dd"} = "OMG OMG\n";
my ( $var, $arrRef, $hashRef ) = cat($test) ;
print "var " . Dumper($var) . "\n" ;
print "arrRef " . Dumper($arrRef) . "\n";
print "hashRef " . Dumper($hashRef) . "\n";
Upvotes: 4
Reputation: 106385
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;
Upvotes: 7