Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Passing hashes as arguments to a sub?

by Spidy (Chaplain)
on Nov 28, 2005 at 17:44 UTC ( #512300=perlquestion: print w/ replies, xml ) Need Help??
Spidy has asked for the wisdom of the Perl Monks concerning the following question:

I have a hash(%arguments), which has all of the arguments passed to my script. I have a function that is supposed to take this hash, check for certain keys, and then do things based on it. How would I go about passing the hash to my function? I've used
my ($varOne,$varTwo) = @_;
For passing multiple arguments as scalars/arrays...but I don't think that would work with a hash. Anyone know how I'd do it?

Thanks,
Spidy

Comment on Passing hashes as arguments to a sub?
Download Code
Re: Passing hashes as arguments to a sub?
by wfsp (Abbot) on Nov 28, 2005 at 17:50 UTC

    Would this do it?

    my %hash = @_;

    #!/bin/perl5 use strict; use warnings; my %hash = ( one => 1, two => 2, ); my_sub(%hash); sub my_sub{ my %hash = @_; for my $key (keys %hash){ print "$key -> $hash{$key}\n"; } }

    update: added snippet

    .

Re: Passing hashes as arguments to a sub?
by ikegami (Pope) on Nov 28, 2005 at 17:54 UTC

    Only scalars can be passed as arguments, so either need to pass a reference (like in the first and second snippet), or flatten the hash into a list of scalars (like in the third snippet).

    One usually passes a reference to the hash which saves Perl from copying the entire hash:

    sub function { my ($hash_ref) = @_; foreach (keys %$hash_ref) { ... } } function(\%hash);
    If you don't with to work with references, you could use an alias:
    sub function { our %hash; local *hash = \$_[0]; foreach (keys %hash) { ... } } function(\%hash);
    Or you could create a copy of the hash if it's the last argument:
    sub function { my %hash = @_; foreach (keys %hash) { ... } } function(%hash);
Re: Passing hashes as arguments to a sub?
by rinceWind (Monsignor) on Nov 28, 2005 at 18:00 UTC

    As wfsp has said, you can just assign @_ and this will treat the passed list of parameters as a set of key and value pairs. Note that an odd number of params will result in a run time exception.

    But, you often want to perform some (often elementary) validation on the input parameters, before casting them to a hash, such as checking that the keys are what you expect. Params::Validate is what I tend to use to do this, though there are other CPAN modules which do similar things. There are plenty of examples of how to use it in the docs.

    --

    Oh Lord, won’t you burn me a Knoppix CD ?
    My friends all rate Windows, I must disagree.
    Your powers of persuasion will set them all free,
    So oh Lord, won’t you burn me a Knoppix CD ?
    (Missquoting Janis Joplin)

Re: Passing hashes as arguments to a sub?
by eff_i_g (Curate) on Nov 28, 2005 at 18:11 UTC
    I'm not familiar with Params::Validate that was mentioned; however, there is a simple example of being strict with hash keys in "Perl Medic." It goes something like this:
    sub name { # this puts the passed list into a hash my %arg = @_; # this transfers values to variables and removes the keys my ($key1, $key2) = delete @arg{qw(key1 key2)}; # this determines if any keys are leftover croak 'Illegal arguments' if %arg; }
      #make hash my %junk = ( one=>'123123', two=>'dsf4f3' ) # send reference &printvals(\%junk); sub printvals { my $junk=$_[0]; #dereference these guys print $$junk{one} . $$junk{two}; }
Re: Passing hashes as arguments to a sub?
by jimbojones (Friar) on Nov 28, 2005 at 21:30 UTC
    Hi
    TheDamian's new book, Perl Best Practices, covers this in Chapter 9. He recommends passing a hash reference, typically to an anonymous hash.

    my $foo = CalcFoo( { bar => 'abc', baz => 'def' } ); sub CalcFoo { my $href = $_[0]; my $foo; if ( defined $href->{bar} and defined $href->{baz} ) { $foo = $href->{bar} . $href->{baz}; } else { print "Error: pls define bar and baz\n"; } return $foo; }
    The reasons given for not passing a list of raw key/value pairs is:
    Requiring the named arguments to be specified inside a hash ensures that any mismatch, such as:
    $line = padded({text=>$line, cols=>20..21, centered=>1, filler=>$SPACE +});
    will be reported (usually at compile time) in the caller’s context:
    Odd number of elements in anonymous hash at demo.pl line 42
    Passing those arguments as raw pairs:
    $line = padded(text=>$line, cols=>20..21, centered=>1, filler=>$SPACE) +;
    would cause the exception to be thrown at run time, and from the line inside the subroutine where the odd number of arguments were unpacked and assigned to a hash:
    The chapter on subroutines is currently available as a sample chapter on the O'Reilly website for you to peruse. It's a great book, highly recommended.

    - j

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://512300]
Approved by NetWallah
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (10)
As of 2014-12-29 15:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (192 votes), past polls