Passing hash to a subroutine

Discussion in 'Perl Misc' started by Ray, Apr 7, 2007.

  1. Ray

    Ray Guest

    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
     
    Ray, Apr 7, 2007
    #1
    1. Advertising

  2. Ray <> wrote:
    > 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 @_;


    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
    --
    \ Jens Thoms Toerring ___
    \__________________________ http://toerring.de
     
    Jens Thoms Toerring, Apr 7, 2007
    #2
    1. Advertising

  3. Ray <> wrote:


    > 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


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Apr 7, 2007
    #3
  4. Ray

    Ray Guest

    Hi Michele,

    On Apr 7, 10:35 pm, Michele Dondi <> wrote:
    > On 7 Apr 2007 04:46:25 -0700, "Ray" <> wrote:
    >
    > >I made a small example to demonstrate my problem:

    >
    > 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!

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


    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
     
    Ray, Apr 9, 2007
    #4
  5. Ray

    Ray Guest

    Hi Tad,

    On Apr 7, 11:13 pm, Tad McClellan <> wrote:
    > Ray <> wrote:
    > > 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.


    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
     
    Ray, Apr 9, 2007
    #5
  6. Ray <> wrote:
    > On Apr 7, 11:13 pm, Tad McClellan <> wrote:


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


    > 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}[].


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Apr 9, 2007
    #6
  7. Ray

    Ray Guest

    Hi Tad,

    On Apr 9, 8:55 pm, Tad McClellan <> wrote:
    > Ray <> wrote:
    > > On Apr 7, 11:13 pm, Tad McClellan <> wrote:
    > >> What you haven't figured out is how to dereference it within
    > >> the function body.

    > > 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
     
    Ray, Apr 19, 2007
    #7
  8. Ray

    Ray Guest

    Hi Michele,

    On Apr 9, 6:02 pm, Michele Dondi <> wrote:
    > On 8 Apr 2007 21:23:43 -0700, "Ray" <> wrote:
    >
    > >> > printf (STDOUT "* %s\n", %{$href} -> {"San Francisco"}{"LA"});

    >
    > >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

    >
    > 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
     
    Ray, Apr 19, 2007
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    6
    Views:
    2,773
    Eric Bohlman
    Apr 4, 2005
  2. rp
    Replies:
    1
    Views:
    592
    red floyd
    Nov 10, 2011
  3. Scott
    Replies:
    10
    Views:
    230
    Tad McClellan
    Dec 7, 2004
  4. Dean
    Replies:
    3
    Views:
    201
  5. king
    Replies:
    5
    Views:
    210
Loading...

Share This Page