I know this should be easily searchable on google, not to mention a trivial use of perl, but I've tried many solutions I've found and so far none of them gives the expected behavior. Essentially, I'm trying to call a subroutine, return a reference to a hash from that subroutine, pass a reference to that hash to another subroutine, and then print the contents of that hash, via code similar to the following:
#!/usr/bin/perl
my $foo = make_foo();
foreach $key (sort keys %$foo) {
print "2 $key $$foo{$key}\n";
}
print_foo(\%foo);
sub print_foo
{
my %loc = ???;
foreach $key (sort keys %loc}) {
print "3 $key $loc{$key}\n";
}
}
sub make_foo
{
my %ret;
$ret{"a"} = "apple";
foreach $key (sort keys %ret) {
print "1 $key $ret{$key}\n";
}
return \%ret;
}
Can someone tell me the best way of doing this (via subroutines) without creating an extra copy of the hash? The solutions I've tried have not printed out any lines starting with "3".
You have to pull the parameters in as a reference and then dereference it:
sub print_foo
{
my ($loc) = @_;
foreach my $key (sort keys %$loc) {
print "3 $key $loc->{$key}\n";
}
}
Anytime you make a reference, you have to explicitly dereference it. Also, beware that any changes to the reference will change the original. If you want to avoid changing the original, you can either pass the hash as a list:
print_foo(%foo); # flattens the hash to a list and passes it in through @_
sub print_foo
{
my (%loc) = @_; # load the hash from the list
foreach my $key (sort keys %loc) {
print "3 $key $loc{$key}\n";
}
}
Or copy the hash reference into a new hash:
sub print_foo
{
my ($ref_loc) = @_; # changes to %$ref_loc will change %foo
my %loc = %$ref_loc; # COPY, changes to %loc do not change %foo
foreach my $key (sort keys %loc}) {
print "3 $key $loc{$key}\n";
}
}
Everything else is good, so I'm just going to concentrate on print_foo...
sub print_foo
{
my %loc = %{shift @_};
foreach $key (sort keys %loc) {
print "3 $key $loc{$key}\n";
}
}
FYI, you need to realize that %loc is now a COPY of the hash (I asked a question which explains this here: Confusion about proper usage of dereference in Perl ). To avoid making a copy...
sub print_foo
{
my $loc = shift @_;
foreach $key (sort keys %$loc) {
my $val = $loc->{$key}
print "3 $key $val\n";
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With