#!/usr/bin/perl
use Data::Dumper;
sub giveMeARef {
my %hash = %{$_[0]};
print "arg: ", Dumper($_[0]);
print "deref: ", Dumper(%hash);
}
my %hash = ( "a" => (1,2,3), "b" => (3,4,5));
giveMeARef(\%hash);
This produces the following output:
arg: $VAR1 = {
'2' => 3,
'4' => 5,
'a' => 1,
'b' => 3
};
deref: $VAR1 = 'b';
$VAR2 = 3;
$VAR3 = '2';
$VAR4 = 3;
$VAR5 = 'a';
$VAR6 = 1;
$VAR7 = '4';
$VAR8 = 5;
I tried to follow the examples in How do I dereference a Perl hash reference that's been passed to a subroutine?
But I believe because my hash is more complicated, it isn't working out for me. How do I get back to the original structure I passed in?
As I mentioned in my comment, you're flattening a list when you create %hash
. The fat comma (=>
) is a synonym for the comma that causes barewords on the left to be interpreted as strings, but it doesn't matter in this case because you've already got a string on the left. In effect, your hash assignment really looks like this:
my %hash = ("a", 1, 2, 3, "b", 3, 4, 5);
It looks like you were trying to assign arrays to a
and b
, but in Perl, hash values are always scalars, so you need to use references to anonymous arrays instead:
my %hash = (a => [1, 2, 3], b => [3, 4, 5]);
It's also worth noting that your subroutine is making a shallow copy of the hash reference you pass in, which may have unintended/unforeseen consequences. Consider the following:
use Data::Dump;
sub giveMeARef {
my %hash = %{$_[0]};
pop(@{$hash{a}});
}
my %hash = (a => [1, 2, 3], b => [3, 4, 5]);
dd(\%hash);
giveMeARef(\%hash);
dd(\%hash);
Which outputs:
{ a => [1, 2, 3], b => [3, 4, 5] }
{ a => [1, 2], b => [3, 4, 5] }