Reputation: 13804
#!/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?
Upvotes: 0
Views: 150
Reputation: 2221
There are two issues here:
The way Dumper is used to print the hash without passing reference wherein it resolves to print all the elements as $VAR1, $VAR2, etc.
Dumper(\%hash)
The way the hash is initialized. Since the value is a list, it should be initialized as
my %hash = ( "a" => [1,2,3], "b" => [3,4,5]);
A more correct code.
#!/usr/bin/perl
use Data::Dumper;
sub giveMeARef {
my %hash = %{$_[0]};
print "arg: ", Dumper($_[0]); #Dumper is passed a Ref.
print "deref: ", Dumper(\%hash); # Dumper should be called with a hash ref.
}
my %hash = ( "a" => [1,2,3], "b" => [3,4,5]);
giveMeARef(\%hash);
Upvotes: 1
Reputation: 6553
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] }
Upvotes: 6
Reputation: 262464
The code is fine, but your test hash is not what you think it is.
You cannot construct a hash like that. The lists in there got flattened out. You need to use array-refs instead:
my %hash = ( "a" => [1,2,3], "b" => [3,4,5]);
Since you are going to take a reference to that hash anyway, you might as well start there:
my $hash_ref = { a => [1,2,3], b => [3,4,5] };
Upvotes: 3