Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

passing paramters to a sub

by jimbus (Friar)
on Aug 29, 2005 at 22:13 UTC ( #487580=perlquestion: print w/replies, xml ) Need Help??
jimbus has asked for the wisdom of the Perl Monks concerning the following question:


I'm confused by something that seems it should be simple. How do I pass a $ and a % to a sub?

I was trying

whatever(%list,$val); ... sub whatever { my %list = $_[0]; my $val = $_[1]; ... }

which got me the first value of the hash. I thried @_ which got me the hash, but lost the value... It seems like it kept returning the value from the first call, but it might be just random.



Never moon a werewolf!

Replies are listed 'Best First'.
Re: passing paramters to a sub
by sh1tn (Priest) on Aug 29, 2005 at 22:26 UTC
    You should pass reference to hash:
    whatever(\%list,$val); ... sub whatever { my %hash = %{$_[0]}; # my $hash_ref = $_[0]; my $val = $_[1]; ... }
    perlsub manual.

Re: passing paramters to a sub
by saberworks (Curate) on Aug 29, 2005 at 23:38 UTC
    Or you could pass the scalar first, like:

    sub whatever { my $scalar = shift; my %hash = @_; }

    Then call it like:

    whatever($scalar, %hash);
    This also passes by VALUE not by reference... so in the other examples of passing a hashref, if you modify the hash inside your sub, it will modify it globally. In this case, you will get copies of your hash (assuming it doesn't also contain references), so if you modify it, it won't show up in the outer part of the program (just in your sub).
Re: passing paramters to a sub
by Tanktalus (Canon) on Aug 29, 2005 at 22:24 UTC
    whatever(\%list, $val); ... sub whatever { my %list = %{$_[0]}; my $val = $_[1]; ... }

    You should cozy up to a nice cup of coffee (or a cold beer, your choice) and go over perlsub :-)

    Update: Of course, ambrus is right. I suppose I need to cozy up and go over perlref again ;-)

      You must surely mean %{$_[0]}, not %$_[0].

Re: passing paramters to a sub
by GrandFather (Sage) on Aug 29, 2005 at 22:22 UTC

    First off, you are passing a hash, but calling it list so the example below uses a list (array).

    use strict; use warnings; my @list = (1, 2, 3, 4); my $value = 10; whatever (\@list, $value); sub whatever { my @localList = @{$_[0]}; #Deref first (reference) param my $localValue = $_[1]; print join ", ", @localList; print " - $localValue"; }

    You need to pass the array as a reference because otherwise it will be flattened, which is not what you want.

    Perl is Huffman encoded by design.
Re: passing paramters to a sub
by InfiniteSilence (Curate) on Aug 29, 2005 at 22:23 UTC
    use references, i.e.
    U:\>perl -MData::Dumper -e "sub whatever {$aref = @_[0]; print $aref- +>[1]}; @aa= (1..5); whatever(\@aa);" 2 U:\>

    Celebrate Intellectual Diversity

Re: passing paramters to a sub
by monarch (Priest) on Aug 30, 2005 at 02:58 UTC
    There'd be no harm in:
    sub whatever( @ $ ); # declaration whatever(%list,$val); sub whatever( @ $ ) { my $val = pop( @_ ); my %list = @_; ... }
        I use prototypes for one and one reason only.

        Compile-time checking.

        So I'd argue that prototypes are still desirable, even with the pop.

Re: passing paramters to a sub
by Roger (Parson) on Aug 30, 2005 at 09:18 UTC
    Other monks have already pointed you in the right direction with passing structures by reference.

    I just want to point out that it is possible not to pass by reference for your benefit.

    A simple hash basically has keys and corresponding values. Knowning this, you can write your code like this:
    whatever(%hash, $val) ... sub whatever { my $v = pop; my %h = @_; # %hash was expanded into list of key-value pairs # reconstruct hash from array of key-value pairs ... }

Re: passing paramters to a sub
by rupesh (Hermit) on Aug 30, 2005 at 05:51 UTC

    Using references is a recommended way of passing hashes to subroutines.
    my %hash = ( foo => "one", bar => "two", foobar => "three", ); my %values = func(\%hash); sub func { my $h_ref = shift; my %newhash; foreach my $key (sort keys %$h_ref) { print "$key => ", $h_ref->{$key}, "\n"; $newhash{$key}=$h_ref->{$key} if $key =~ /regexp/; } return \%newhash; }
Re: passing paramters to a sub
by jimbus (Friar) on Aug 30, 2005 at 15:17 UTC

    Thanks all!

    I picked up perl, initially, from hacking other people's code. I came back to it recently because of the frustration of using stock Unix shells to parsing logs and have been working out of O'Reily's Perl Cookbook and google searches.

    If you've read some of my other post, you've probably heard me rant about not being able to find best practices and perl patterns. This kind of falls into that category. I spent more than a half hour going through the book and googling for "perl sub parameters" and "perl sub parameters hashes" and couldn't find anything that did something as basic pass multiple parameters. I really haven't needed to use subs, but I probably should get into the habit again, to improve readability. Scanning through the PerlDoc page listed, I found the section discussing passing multiple data structures by reference... something else I've been avoiding and need to embrace, using references.

    Perhaps there's a better way to do what I'm doing? I have to compare filenames in a CSV with an actualy directory listing. I'm comfortable with parsing the CSV and populating a hash with the filenames and the value 1. I 'm comfortable with ftping to the remote machine and getting a list of files and updateing the hash with += 2, so that I end up with a 1, 2 or 3 for each member, depending on whether the file is in one, the other or both. What I think is messy is the reporting. I'm basically walking through the hash three times to say print each 3, print each 2, print each 1. Is there a more efficient way to pull this off?

    Thanks again!


    Never moon a werewolf!

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://487580]
Approved by GrandFather
and the fog begins to lift...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2017-02-24 00:04 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (351 votes). Check out past polls.