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

I have a hash (%amazonResults) and hashref from Config::INI:Simple ($conf) I am trying to pass to a sub. When I do a print Dumper of both, everything looks find
print Dumper %amazonResults; print Dumper $conf; &processAmazonQuery(%amazonResults, $conf);
Once I pass them over to processAmazonQuery, the Dumper for $conf is blank.
sub processAmazonQuery { my (%hash, $conf) = @_; print "hash\n"; print Dumper %hash; print "conf\n"; print Dumper $conf; |
Thanks in advance!

Replies are listed 'Best First'.
Re: Passing hash and hashref to sub
by davorg (Chancellor) on Jul 27, 2008 at 10:17 UTC

    Your problem in in this line:

    my (%hash, $conf) = @_;

    List assignment is greedy. So the hash takes all of @_ leaving nothing to go into $conf. If you had "use warnings" turned on then you'd get the error about using a list with an odd number of elements to create a hash.

    There are (at least) three solutions:

    1. Pass the parameters the other way round.

    my ($conf, %hash) = @_;

    2. Use "pop" to get $conf.

    my $conf = pop @_; my $hash = @_;

    3. Pass in a hash reference instead of the hash.

    my ($hash_ref, $conf) = @_;
    --

    See the Copyright notice on my home node.

    "The first rule of Perl club is you do not talk about Perl club." -- Chip Salzenberg

      Thank you all very much!
Re: Passing hash and hashref to sub
by FunkyMonk (Bishop) on Jul 27, 2008 at 10:33 UTC
    print Dumper %amazonResults

    You'll get prettier output if you make a reference from your hash: \%amazonResults. Also look at Data::Dump. It gives you a better (IMO, of course) looking output and a better interface (pp \%amazonResults instead of print Dumper ...).

    &processAmazonQuery(...)

    Please get out of the habit of prefixing subroutine calls with "&". It'll just lead to mysterious bugs sooner or later.

    my (%hash, $conf) = @_

    You can't pass a hash into a subroutine like that. %hash will take everything from @_ leaving nothing for $conf. Either use a hashref in your call: processAmazonQuery(\%amazonResults, $conf) and my ($hashref, $conf) = @_; my %hash = %$hashref in your sub (or rewirite the sub to use the reference instead).

    Or, you could use my $conf = pop @_; my %hash = @_

    I'd recommend rewriting the sub so it uses a hashref instead of a hash.


    Unless I state otherwise, all my code runs with strict and warnings
Re: Passing hash and hashref to sub
by dHarry (Abbot) on Jul 27, 2008 at 10:09 UTC

    Pass arrays and hashes by reference, using the backslash operator: "\"

    This actually from The Perl Cookbook: Section 10.5. Passing Arrays and Hashes by Reference. Get yourself a copy it's good value for money!

    Hope this helps.

Re: Passing hash and hashref to sub
by toolic (Bishop) on Jul 27, 2008 at 12:40 UTC
    While we're discussing references, and since no one explicitly mentioned this, also pass references to Dumper:
    print Dumper(\%amazonResults);

    For more information on references, read the free manual: perlref

Re: Passing hash and hashref to sub
by chrism01 (Friar) on Jul 28, 2008 at 09:41 UTC
    TMTOWTDI

    processAmazonQuery($conf, %amazonResults);

    sub processAmazonQuery { my $conf = shift(@_); my %hash = @_;