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

I have the following code..
and my question is...

why is there a need for a "\" before the hashes when I pass them in as arguments to a subroutine?

sub process($$$) { my($path, $seen, $total) = @_; # do something... } my %seen; my %total; foreach my $path (@ARGV) { process($path, \%seen, \%total); }

Edit: chipmunk 2001-06-03

Replies are listed 'Best First'.
Re: why a
by mpolo (Chaplain) on Jun 03, 2001 at 12:16 UTC
    The backslash creates a reference to the hash, rather than passing the actual hash. This is useful to separate two hashes that you are passing at the same time -- and is also recommendable for arrays.

    If you pass two arrays to a subroutine without making references, what the subroutine actually sees is one big array combining the two, and your subroutine would have to "know" how to split them apart. The same would apply with hashes.

    Since you've passed them as references, they will be scalar variables when they arrive at the subroutine, and you will have to de-reference them with the % or @ funny symbol.

    process($path, \%seen, \%total); sub process { my ($path, $seen, $total) = @_; my %totalhash=%{$total}; ... }
Re: why a
by larryk (Friar) on Jun 03, 2001 at 15:22 UTC
    Just another point, passing the hashes as references means that at the other end you just have a "pointer" to the position in memory that the hash starts at. The data itself is not "copied" so you don't double the memory requirements. It also means that if you change any of the data inside the hash, it is the original that is modified. Consider the following code...
    #!perl -w use strict; my %hash = ( a => 1, b => 2, c => 3 ); sub change { my $hash = shift; $hash->{c} = 4; } change( \%hash ); for my $key (sort keys %hash) { print "$key : $hash{$key}\n"; } __END__ Output looks like: a : 1 b : 2 c : 4
    The original was modified and without the hash being returned by the sub.

    Hope this helps

    "Argument is futile - you will be ignorralated!"

Re: why a
by rob_au (Abbot) on Jun 03, 2001 at 12:17 UTC
    In addition to what mpolo has already written, see perlman:perlref for further information on references.

    Ooohhh, Rob no beer function well without!

Re: why is a "\" needed before a hash in my subroutine call?
by chipmunk (Parson) on Jun 03, 2001 at 19:06 UTC
    By the way, if you changed the function prototype to this:
    sub process ($\%\%) { my($path, $seen, $total) = @_; # do something... }
    then you would (have to) call the function without putting a backslash before each hash:
    my %seen; my %total; foreach my $path (@ARGV) { process($path, %seen, %total); }
    The calling code specifies a bare hash, but Perl still puts a references to the hash in @_.

    Personally, I prefer not to use prototypes; I would leave off the prototype definition and pass in explicit hash references.

(prototypes) Re: why a
by Zaxo (Archbishop) on Jun 03, 2001 at 18:47 UTC

    The reason the compiler is insisting on the backslash is that you have prototyped the function to take three scalars. That enforces correct use when the code inside depends on dereferencing things.

    After Compline,
    Zaxo

      That enforces correct use...

      but only if the function was called using the name(args) syntax - the compiler doesn't enforce the prototype when the & syntax is used, or if the sub is called via a reference:

      &process($path, %seen, %total); # won't complain my $sub = \&process; $sub->($path, %seen, %total); # won't complain

      Jeff

      R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
      L-L--L-L--L-L--L-L--L-L--L-L--L-L--