ewhitt has asked for the wisdom of the Perl Monks concerning the following question:

Hello Perlmonks,

I am trying to pass and return 2 HoA's and 1 Array. I created a test script to see if this was possible, but I can't get it to work
#!/usr/bin/perl use Data::Dumper; use strict; my %HoA1; my %HoA2; push(@{$HoA1{"HOA-1"}}, "Entry One"); push(@{$HoA2{"HOA-2"}}, "Entry One"); my @a = qw(entry1 entry2 entry3); sub test { my ($HoA1,$HoA2,@a,$test) = @_; push(@{$HoA1{"HOA-1"}}, "Entry Two"); push(@{$HoA2{"HOA-2"}}, "Entry Two"); print "Array: @a\n"; print "Test : $test\n"; return ($HoA1,$HoA2); } ($HoA1,$HoA2) = test($HoA1,$HoA2,@a, "test"); print Dumper(%HoA1); print "\n\n"; print Dumper(%HoA2);
How far off am I? Thanks!

Replies are listed 'Best First'.
Re: Passing and returning multiple HoA's with Array to sub
by ikegami (Patriarch) on Dec 12, 2009 at 09:37 UTC

    First, there's the problem that you're passing non-existent variables $HoA1 and $HoA2 to the sub. (Yay for using use strict;!)

    You want to pass the hashes, but you can't do that. You can only pass scalars as arguments. So let's pass a reference to the hash instead.

    test(\%HoA1, \%HoA2, ...);

    Then there's the problem that

    test(\%HoA1, \%HoA2, @a, "test");
    is the same thing as
    test(\%HoA1, \%HoA2, "entry1", "entry2", "entry3", "test");

    When you do

    my ($HoA1,$HoA2,@a,$test) = @_;

    there no way for Perl to know how many of the remaining args go in @a, so they all go into @a.

    Just like with the hashes, you'll need to pass a reference to the array, not the contents of the array.


    All together, we have:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; sub test { my ($HoA1, $HoA2, $a, $test) = @_; push(@{$HoA1->{"HOA-1"}}, "Entry Two"); push(@{$HoA2->{"HOA-2"}}, "Entry Two"); print "Array: @$a\n"; print "Test: $test\n"; } my %HoA1; my %HoA2; push(@{$HoA1{"HOA-1"}}, "Entry One"); push(@{$HoA2{"HOA-2"}}, "Entry One"); my @a = qw(entry1 entry2 entry3); test(\%HoA1, \%HoA2, \@a, "test"); print Dumper(\%HoA1); print Dumper(\%HoA2);

    Note that I removed the return value since it's not needed. Since you're modifying the caller's hash through the reference, the caller already sees the changes being made by the sub.

    Tip: Dumper's argument is a scalar. Don't pass a hash. If you want to dump a hash or array, pass a reference to it. It'll be much easier to read.

    Update: Missed the first problem originally. Added the bit addressing it.

Re: Passing and returning multiple HoA's with Array to sub
by GrandFather (Saint) on Dec 12, 2009 at 09:43 UTC

    What do you mean by "can't get it to work"? What do you understand by the error message that running the script gives? Hint: 'Global symbol "x" requires explicit package name' generally translates as '"x" is undefined'.

    Oh, another hint: \%HoA is a reference to %HoA.


    True laziness is hard work