Passing hash to a subroutine

R

Ray

Hi all,

I've been trying to figure out how to pass a hash (and a hash of
hashes) into a function. After some fiddling around and reading
perlreftut, I think I got it. However, I turned on "use strict" and
it is warning me that what I am doing is "deprecated" and may not be
supported in the future. So, even though it works (I mean...I get the
right answer), can someone tell me what the supported way?

I made a small example to demonstrate my problem:

-----
#!/usr/bin/perl -w
use strict;
use diagnostics;

my %cities;
my %states;

sub printStates {
my $href = shift @_;

## Next line is deprecated
printf (STDOUT "* %s\n", %{$href} -> {"New York"});
}

sub printCities {
my $href = shift @_;

## Next line is also deprecated
printf (STDOUT "* %s\n", %{$href} -> {"San Francisco"}{"LA"});
}

$cities{"San Francisco"}{"LA"} = "near";
$cities{"San Francisco"}{"New York"} = "far";
$states{"San Francisco"} = "California";
$states{"New York"} = "New York";

printf (STDOUT "%s\n", $cities{"San Francisco"}{"LA"});
printf (STDOUT "%s\n", $cities{"San Francisco"}{"New York"});

printf (STDOUT "%s\n", $states{"San Francisco"});
printf (STDOUT "%s\n", $states{"New York"});

printf (STDOUT "%s\n", \%states);

printStates (\%states);
printCities (\%cities);
-----

The warnings are:

Using a hash as a reference is deprecated at ./foo.pl line 11 (#1)
(D deprecated) You tried to use a hash as a reference, as in
%foo->{"bar"} or %$ref->{"hello"}. Versions of perl <= 5.6.1
used to allow this syntax, but shouldn't have. It is now
deprecated, and will
be removed in a future version.

Using a hash as a reference is deprecated at ./foo.pl line 17 (#1)

which are good in telling me what I did wrong, but I have no clue on
how to correct it. Any ideas?

Thanks in advance!

Ray
 
J

Jens Thoms Toerring

Ray said:
I've been trying to figure out how to pass a hash (and a hash of
hashes) into a function. After some fiddling around and reading
perlreftut, I think I got it. However, I turned on "use strict" and
it is warning me that what I am doing is "deprecated" and may not be
supported in the future. So, even though it works (I mean...I get the
right answer), can someone tell me what the supported way?
I made a small example to demonstrate my problem:
my %cities;
my %states;
sub printStates {
my $href = shift @_;

A simple

my $href = shift;

will also do.
## Next line is deprecated
printf (STDOUT "* %s\n", %{$href} -> {"New York"});

That looks rather strange (and, yes, it's deprecated). Just use

printf (STDOUT "* %s\n", $href->{"New York"});

It looks simpler and makes the warning go away;-)

When you have a hash you access the values the reference points to
using the '->' after the reference (the same holds if you have an
array reference). E.g.

my %h = (a => 1, b => 2);
my $hr = \%h;
print "$h{a} == $hr->{a}\n";

my @a = (1, 2);
my $ar = \@a;
print "$a[0] == $ar->[0]\n";

Regards, Jens
 
T

Tad McClellan

I've been trying to figure out how to pass a hash (and a hash of
hashes) into a function.


You *have* figured out how to pass a hash into a function.

What you haven't figured out is how to dereference it within
the function body.

After some fiddling around and reading
perlreftut, I think I got it.


perlreftut describes two different ways of dereferencing.

You are applying *both* ways.

can someone tell me what the supported way?


Deferencing once, using either way, is the supported way.

sub printStates {
my $href = shift @_;

## Next line is deprecated
printf (STDOUT "* %s\n", %{$href} -> {"New York"});
}


printf (STDOUT "* %s\n", ${$href}{"New York"}); # Use Rule 1
or
printf (STDOUT "* %s\n", $href->{"New York"}); # Use Rule 2
 
R

Ray

Hi Michele,

In my first post I addressed your immediate problem. There are more
issues with your code, though. I will briefly go through them now.

Yes, thank you that! It was very helpful! And for cleaning up my
Perl code. I've been doing a few things in Perl which compile but
aren't very Perl-ish and am changing at a very slow pace. So, thanks!

And you also caught me. I am originally a C-programmer and changing to
a Perl programming means my Perl code sometimes looks like C. Thanks
again -- I'll use what you suggested from now on.

Ray
 
R

Ray

Hi Tad,

You *have* figured out how to pass a hash into a function.

What you haven't figured out is how to dereference it within
the function body.

Yes, that's what I was thinking.
perlreftut describes two different ways of dereferencing.

You are applying *both* ways.

Ah! Thank you. I was just looking back at perlreftut to see where I
went wrong. I guess read @a and @{$aref} were equivalent and
mistakenly kept modifying this until it worked instead of looking at
it more carefully. My biggest mistake was thinking that references
were somehow different if I passed it in a function, but it doesn't
seem to be.

Thanks again!

Ray
 
T

Tad McClellan

I was just looking back at perlreftut to see where I
went wrong. I guess read @a and @{$aref} were equivalent and


And they *are* equivalent!

But you didn't want the whole aggregate (array above but hash earlier).

You wanted to index into the aggregate, so you needed the
equivalent of $a[], which is ${$aref}[].
 
R

Ray

Hi Tad,

Ray said:
I was just looking back at perlreftut to see where I
went wrong. I guess read @a and @{$aref} were equivalent and

And they *are* equivalent!

But you didn't want the whole aggregate (array above buthashearlier).

You wanted to index into the aggregate, so you needed the
equivalent of $a[], which is ${$aref}[].

I see -- I guess the equivalence between the two wasn't immediately
obvious to me. They look so different -- but thanks for this!

Ray
 
R

Ray

Hi Michele,

Well... that is, in $Larry's words, "officially ok". But using a
simple print() where it suffices has obvious advantages. It's much
like when you learn a foreign language and it's fine if you initially
use its constructs that most resemble your mother tongue, even if
they're obsolete or unusual; but as you learn more and more you switch
to more idiomatic ones.

Interesting analogy. Alas, it's hard to break old habits, especially
if your first language (C or English :) ) has been with you for so
long. But not impossible; hopefully not yet old enough to not being
able to learn new tricks! ;-) Thanks!

Ray
 

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,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top