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

Hello All! This is my first post. I hope to learn much at this forum and help others as well. Now my question: I have a problem.. I have not yet properly understood how to use references. I need to pass a hash of arrays to a subrutine. Im not sure how to do this. Could you help me or maybee give me a link to a good general text about references that is easy to understand? Thank you for any help.

Replies are listed 'Best First'.
Re: hash of arrays to a subrutine?
by Corion (Patriarch) on Jan 04, 2006 at 10:51 UTC

    Hello tamaguchi
    First of all, welcome to the monastery! We will try to help you with most of your Perl related questions (and some non-Perl related questions too). For getting a quick grip on references, I suggest tyes References Quick Reference.

    I saw that you changed your title from "Hello All" to "hash of arrays to a subrutine?" - this is very good. The choice of a good title helps the readers to quickly understand your question and also helps you, the author, to take a step back and reflect on what your question actually is.

    Update: I completely forgot to add a simplicistic example of how to pass a hash of arrays to a subroutine:

    my %players = ( frodo => [ 'ring', 'chainmail armour' ], sam => [ 'lembas', 'chainmail armour' ], smeagol => [ 'fish', 'rabbit' ], ); # Pass the hash as a list: sub print_players { my (%players) = @_; for my $player (keys %players) { printf "$player: %s\n", join ",",@{$players{$player}}; }; }; # Pass the hash as a reference: sub print_players_ref { my ($players) = @_; for my $player (keys %$players) { printf "$player: %s\n", join ",",@{$players->{$player}}; }; }; print_players(%players); print_players_ref(\%players);
      What would you consider to be the advantage of using references compaired to not using them? What is the difference? Would a large program generally run faster when references are used compaired to when they are not used?

        "It depends". In general, you can regard a reference as the key to a locker. Instead of passing around the things in the locker, you pass around the key. So, references can be used to avoid copying of values, but they are more expensive on overall access. So if you have "large" values, it can be worthwhile to pass them around as references, but Data::Alias might be a better and less convoluted way of avoiding passing around the references.

Re: hash of arrays to a subrutine?
by Fang (Pilgrim) on Jan 04, 2006 at 11:02 UTC

    Hello and welcome tamaguchi.

    One of the best starting point for references that I know of is the perlreftut man page, available online or on your system by issuing the perldoc perlreftut command. It should get you started on solid ground. If you need more infos, the book Learning Perl Objects, References and Modules is an excellent ressource, having 5 chapters about references, from introduction to tricks and recipe-like examples.

    After that, if you still have some unanswered questions, there is perlmonks.org. But I'm sure you know about that one already.

    Update: completely forgot about the technical part of your question about passing by reference a hash of arrays to a subroutine. Here's how you could do it.

    my %HoA = ( foo => [ 'bar', 'baz' ], qux => [ 'thud', 'xyz' ], ); mysub(\%HoA); # pass a reference of the data structure sub mysub { my $hash_ref = shift; # or if you want to directly work with a hash # instead of a reference inside the sub you can use # my %HoA = %{ shift }; # Then you can do your stuff... }

    If any of the above code looks unclear to you, start by reading the perlreftut doc, it should all suddenly make sense.

    Once you're more at ease with references, you will certainly want to have a look at the Perl Data Structures Cookbook, as well as at the complete references documentation.

Re: hash of arrays to a subrutine?
by cog (Parson) on Jan 04, 2006 at 10:50 UTC
Re: hash of arrays to a subrutine?
by DungeonKeeper (Novice) on Jan 04, 2006 at 12:59 UTC
    Sub( \%hash ); sub Sub { # example avoiding copying data around in bulk. my $href = shift; for my $aref ( keys %$href ) { # loop the hash for ( my $idx=0; $idx <= $#$aref; $idx++ ) { # loop array Process( $aref -> [$idx] ); } } } sub Process { my $scalar = shift; # whatever with the array element }