Catch hash correctly in subroutine

B

Bart Van der Donck

Hello,

I am trying to catch a hash in its original form in a subroutine,
between other variables.

my $a1 = 'str1';
my %b = ( '1' => 'a', '2' => 'b' );
my $a2 = 'str2';
show($a1, %b, $a2);
sub show {
print $_[2];
}

I expected this to print 'str2', and $_[1] to become a reference to
%b, but it appears @_ holds every single value of the hash in a simple
array. Is there a way to receive "clean" hashes in this subroutine ? $_
[#$_] works in my particular case, but I don't know the length of %b
and the eventual production code will have more hashes to pass, which
I should correctly refer to.

Thanks for any ideas,
 
K

Klaus

Hello,

I am trying to catch a hash in its original form in a subroutine,
between other variables.

    my $a1 = 'str1';
    my %b = ( '1' => 'a', '2' => 'b' );
    my $a2 = 'str2';
    show($a1, %b, $a2);

In order for $_[1] to become a reference, you have to pass a reference
\%b in the subroutine call

show($a1, \%b, $a2);
    sub show  {
      print $_[2];
    }

I expected this to print 'str2', and $_[1] to become a reference to
%b, but it appears @_ holds every single value of the hash in a simple
array.
 
B

Bart Van der Donck

Klaus said:
  my $a1 = 'str1';
  my %b = ( '1' => 'a', '2' => 'b' );
  my $a2 = 'str2';
  show($a1, %b, $a2);

In order for $_[1] to become a reference, you have to pass a reference
\%b in the subroutine call

That does it. Thanks!
 
J

Jürgen Exner

Bart Van der Donck said:
I am trying to catch a hash in its original form in a subroutine,
between other variables.

What do you mean by "catch"?
my $a1 = 'str1';
my %b = ( '1' => 'a', '2' => 'b' );
my $a2 = 'str2';
show($a1, %b, $a2);

Oh, you meant to "pass" a hash.
sub show {
print $_[2];
}

I expected this to print 'str2', and $_[1] to become a reference to
%b,

You might have expected that, but it's not how Perl is defined.
but it appears @_ holds every single value of the hash in a simple
array.

Yes, that is the normal semantic of function calls in Perl: Arrays and
hashes are flattened when passed as arguments.
Is there a way to receive "clean" hashes in this subroutine ? $_
[#$_] works in my particular case, but I don't know the length of %b
and the eventual production code will have more hashes to pass, which
I should correctly refer to.

You cannot do that, you will have to pass explicit references to those
hashes instead of the hashes themself.

jue
 
T

Tad J McClellan

Bart Van der Donck said:
I am trying to catch a hash in its original form in a subroutine,
between other variables.

my $a1 = 'str1';
my %b = ( '1' => 'a', '2' => 'b' );
my $a2 = 'str2';
show($a1, %b, $a2);
sub show {
print $_[2];
}

I expected this to print 'str2', and $_[1] to become a reference to
%b, but it appears @_ holds every single value of the hash in a simple
array.


If you have a question related to subroutines, you should read the
documentation for subroutines. The 2nd paragraph of the DESCRIPTION
in

perldoc perlsub

points out where your expectation is incorrect:

The Perl model for function call and return values is simple: all
functions are passed as parameters one single flat list of scalars, and
all functions likewise return to their caller one single flat list of
scalars. Any arrays or hashes in these call and return lists will
collapse, losing their identities--but you may always use
pass-by-reference instead to avoid this.


IFF you have only a single array or hash to pass, you can simply
make it the last argument:

show($a1, $a2, %b);
...
sub show {
my($first, $second, %hash) = @_;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top